How to clear canvas in android on button click - android

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class SingleTouchEventView extends View {
private Paint paint = new Paint();
private Path path = new Path();
public boolean cc = false;
public SingleTouchEventView(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setAntiAlias(true);
paint.setStrokeWidth(18f);
paint.setColor(Color.LTGRAY);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
}
#Override
protected void onDraw(Canvas canvas) {
if(cc)
{
Bitmap back = BitmapFactory.decodeResource(getResources(), R.drawable.black_square);
Bitmap cb = Bitmap.createScaledBitmap(back, 0, 0, false);
canvas.drawBitmap(cb,0,0,null);
cc = false;
}
canvas.drawPath(path, paint);
}
public void clearCanvas()
{
cc =true;
invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
// nothing to do
break;
default:
return false;
}
// Schedules a repaint.
invalidate();
return true;
}
}
The above file is my SingleTouchEventView.Java
Here is my MainActivity.java
public class MainActivity extends Activity {
Button reset;;
LinearLayout canvasAlphabets;
SingleTouchEventView myView;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
reset = (Button)findViewById(R.id.reset_canvas);
myView = new SingleTouchEventView(this, null);
canvasAlphabets = (LinearLayout)findViewById(R.id.canvas_Alphabets);
canvasAlphabets.addView(myView);
reset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}
}
My question is what code should I use in reset button to delete all contents of canvas.
Please help me
I have tried implementing myView.clearCanvas() but that doesn't help. If I add this code to reset buutons on Click it causes FC
Thanks

path = new Path();
Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, 0, 0, clearPaint);
cc = false;
I got it fixed with above code

Maybe I do not understand what you want to draw, but have you tried this:
protected void onDraw(Canvas canvas)
{
if (cc)
{
Bitmap back = BitmapFactory.decodeResource(getResources(), R.drawable.black_square);
Bitmap cb = Bitmap.createScaledBitmap(back, 0, 0, false);
canvas.drawBitmap(cb,0,0,null);
cc = false;
}
else
canvas.drawPath(path, paint);
}
}
Otherwise, if you want to erase all, you can use this new paint:
Paint transparent = new Paint();
transparent.setAlpha(0);

You can panit everything with a transparent color, to clear everything.

Related

Changing path color without changing previous paths

I made straight lines with the canvas.drawPath command. But now I want that the color is selectable. So you click on a button and afterwards, the path is in this color, but the previous paths remain in their colors.. The thin with the button comes later, the colour is random at the moment...
I did it, i changed the code from here! Change path color without changing previous paths
Main Activity
package com.example.drawproject;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DrawArea da = new DrawArea(this);
setContentView(da);
}
}
Draw Activity
import android.content.Context;
import android.graphics.*;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class DrawArea extends View {
private List<Stroke> _allStrokes; //all strokes that need to be drawn
private SparseArray<Stroke> _activeStrokes; //use to retrieve the currently drawn strokes
private Random _rdmColor = new Random();
int count = 1;
public DrawArea(Context context) {
super(context);
_allStrokes = new ArrayList<Stroke>();
_activeStrokes = new SparseArray<Stroke>();
setFocusable(true);
setFocusableInTouchMode(true);
}
public void onDraw(Canvas canvas) {
if (_allStrokes != null) {
for (Stroke stroke: _allStrokes) {
if (stroke != null) {
Path path = stroke.getPath();
Paint painter = stroke.getPaint();
if ((path != null) && (painter != null)) {
if(count%2 != 0){
canvas.drawPath(path, painter);
}
}
}
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
final int pointerCount = event.getPointerCount();
switch (action) {
case MotionEvent.ACTION_DOWN: {
count++;
if(count%2 != 1)
{pointDown((int)event.getX(), (int)event.getY(), event.getPointerId(0));
break;
}
if (count%2 != 0){
for (int pc = 0; pc < pointerCount; pc++) {
pointDown((int)event.getX(pc), (int)event.getY(pc), event.getPointerId(pc));
}
}
}
case MotionEvent.ACTION_MOVE: {
break;
}
case MotionEvent.ACTION_UP: {
break;
}
}
invalidate();
return true;
}
private void pointDown(int x, int y, int id) {
if(count%2 !=1){
//create a paint with random color
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10);
paint.setColor(_rdmColor.nextInt());
//create the Stroke
Point pt = new Point(x, y);
Stroke stroke = new Stroke(paint);
stroke.addPoint(pt);
_activeStrokes.put(id, stroke);
_allStrokes.add(stroke);
}
if (count%2 != 0){
//retrieve the stroke and add new point to its path
Stroke stroke = _activeStrokes.get(id);
if (stroke != null) {
Point pt = new Point(x, y);
stroke.addPoint(pt);
}
}
}
}
Lines
package com.example.drawproject;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
public class Stroke {
private Path _path;
private Paint _paint;
public Stroke (Paint paint) {
_paint = paint;
}
public Path getPath() {
return _path;
}
public Paint getPaint() {
return _paint;
}
public void addPoint(Point pt) {
if (_path == null) {
_path = new Path();
_path.moveTo(pt.x, pt.y);
} else {
_path.lineTo(pt.x, pt.y);
}
}
}
For each path declare separate paint object and change paint object of the path that you want to change.
canvas.drawPath(path1, paint1);
canvas.drawPath(path2, paint2);
canvas.drawPath(path3, paint3);
canvas.drawPath(path4, paint4);
The main idea:
public class temp extends View{
private Map<Path,Paint> MyMap = new HashMap<Path,Paint>();
public ViewFeld(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
private void init() {
for (int i = 0; i < number of pathes ; i++) {
Path path = new Path();
paint = new Paint();
paint.setColor(Color.MAGENTA);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.FILL);
MyMap.put(path, paint);
}
}
protected void onDraw(Canvas canvas) {
for (Path p : MyMap.keySet()) {
canvas.drawPath(p, MyMap.get(p));
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Paint p = MyMap.get(path you want to change the color);
// change the color of p
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
// nothing to do
break;
default:
return false;
}
// Schedules a repaint.
invalidate();
return true;
}

Android Canvas Undo and Redo with Bitmap

I'm having problem with undo and redo operations on a canvas.
I noticed the below code works if I don't use canvas.drawbitmap in the Ondraw() method but I need to draw to bitmap so I can save canvas image and as well load image. Kindly help me.
Below is my code.
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.akinslove.drawingapp.activities.DrawingCanvasActivity;
public class DrawView extends View {
// for bitmap
private Bitmap mainBitmap;
private Canvas mainCanvas;
private Paint mainbitmapPaint;
// for canvas
private Path currentPath;
private Paint currentpathPaint;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialiseMyComponents();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
initialiseMyComponents();
}
public DrawView(Context context) {
super(context);
initialiseMyComponents();
}
private void initialiseMyComponents() {
currentPath = new Path();
currentpathPaint = new Paint();
currentpathPaint.setColor(Color.BLACK);
currentpathPaint.setStrokeWidth(10);
currentpathPaint.setStyle(Style.STROKE);
currentpathPaint.setStrokeJoin(Join.ROUND);
currentpathPaint.setStrokeCap(Cap.ROUND);
currentpathPaint.setAntiAlias(true);
mainbitmapPaint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
for (Path p : paths){
canvas.drawPath(p, currentpathPaint);
}
canvas.drawPath(currentPath, currentpathPaint);
**//I wish to use the below line of code
canvas.drawBitmap(mainBitmap, 0, 0, mainbitmapPaint);**
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (mainBitmap == null) {
mainBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
mainCanvas = new Canvas(mainBitmap);
mainCanvas.drawColor(Color.WHITE);
}
}
float lastX;
float lastY;
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
float x = event.getX();
float y = event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
undonePaths.clear();
DrawingCanvasActivity.IMAGEDRAWN = true;
currentPath.moveTo(x, y);
lastX = x;
lastY = y;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
currentPath.quadTo(lastX, lastY, (lastX + x) / 2, (lastY + y) / 2);
mainCanvas.drawPath(currentPath, currentpathPaint);
lastX = x;
lastY = y;
invalidate();
break;
case MotionEvent.ACTION_UP:
currentPath.lineTo(x, y);
mainCanvas.drawPath(currentPath, currentpathPaint);
// kill this so we don't double draw
paths.add(currentPath);
currentPath = new Path();
currentPath.rewind();
invalidate();
break;
}
return true;
}
// method to get bitmap
public Bitmap getMainBitmap() {
return mainBitmap;
}
// method to set bitmap
public void setMainBitmap(Bitmap mpt) {
mainBitmap = mpt;
mainCanvas = new Canvas(mainBitmap);
postInvalidate();
}
public void onClickUndo () {
if (paths.size()>0)
{
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
}
}
public void onClickRedo (){
if (undonePaths.size()>0)
{
paths.add(undonePaths.remove(undonePaths.size()-1));
invalidate();
}
}
}
I just found out that the line mainCanvas.drawPath(currentPath, currentpathPaint); at both case MotionEvent.ACTION_UP: and case MotionEvent.ACTION_MOVE: should not be there. It seems to redraw the path to bitmap and onto the canvas. Not sure if I speak the right android terms.

Make layout by xml instead programmatically

I have this classes
MyTouchEventView.java
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
public class MyTouchEventView extends View {
private Paint paint = new Paint();
private Path path = new Path();
private Path circlePath = new Path();
public Button btnReset;
public LayoutParams params;
public MyTouchEventView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
btnReset = new Button(context);
btnReset.setText("Clear Screen");
params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
btnReset.setLayoutParams(params);
btnReset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
path.reset();
postInvalidate();
}
});
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float pointX = event.getX();
float pointY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(pointX, pointY);
circlePath.reset();
circlePath.addCircle(pointX, pointY, 30, Path.Direction.CW);
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
postInvalidate();
return true;
}
}
DrawingBrush.java
public class DrawingBrush extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyTouchEventView tv = new MyTouchEventView(this);
setContentView(tv);
addContentView(tv.btnReset, tv.params);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
finish();
}
}
Now I want to convert this
MyTouchEventView tv = new MyTouchEventView(this);
setContentView(tv);
addContentView(tv.btnReset, tv.params);
to be as setContentView(R.layout.main); and put the button and other components that in view in "main.xml" layout
how can I do this? hope anyone got my mean.
MyTouchEventView should have at least one more constructor.
This constructor should accept a AttributeSet parameter, besides Context.
public MyTouchEventView (Context context, AttributeSet attrs) {
// perform initialization
}
And it will be invoked when the view is declared in XML layout file.
Then, you would declare the view in XML like this:
<com.my_package_name.MyTouchEventView
....
/>
This topic is explained in detail in Android docs. Have a look here: http://developer.android.com/training/custom-views/index.html

Android Clip drawText to Paint over that text

I am new to 2d graphics..
I create a text using drawText method.
I have to paint over the drawtext area..
how can i clip the area of the text and paint over the surface
package com.example.testingcanvas;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends Activity {
class MyCustomView extends View {
private float x = 0, y = 0;
Path path = new Path();
Paint paint = new Paint();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ii);
private Rect m_ImageRect;
private Rect m_TextRect;
Context m_Context;
// you need these constructor
// you can init paint object or anything on them
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
m_Context = context;
}
public MyCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
m_Context = context;
}
public MyCustomView(Context context) {
super(context);
m_Context = context;
}
// then override on draw method
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(3);
paint.setTextSize(100);
// here frist create two rectangle
// one for your image and two for text you want draw on it
m_ImageRect = canvas.getClipBounds();
m_TextRect = canvas.getClipBounds();
// it gives you an area that can draw on it,
// the width and height of your rect depend on your screen size
// device
canvas.save();
canvas.drawBitmap(bm, null, m_ImageRect, paint);
canvas.drawPath(path, paint);
canvas.restore();
canvas.save();
canvas.clipRect(m_TextRect);
canvas.drawText("A", 100, 300, paint);
// canvas.drawText("A", 20, 20,50,50, paint);
// canvas.restore();
}
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
x = event.getX();
y = event.getY();
path.lineTo(x, y);
break;
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
path.moveTo(x, y);
break;
case MotionEvent.ACTION_UP: {
}
default:
}
invalidate();
return true;
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyCustomView(this));
}
public void onBackPressed() {
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
finish();
onDestroy();
}
}
i am trying to draw over the text area.but i cant get it.

paint canvas android

I'm developing in android, and I have to do a Paint for android.
I'm using the code below and, when I execute the code, the draw works, but, it seems that there are 2 surfaces to paint, and when you draw in one, the other one disappears.
I was looking for the exact error, but cannot find it.
Here is the code :
import java.util.Random;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
MySurfaceView mySurfaceView;
Button Cuadrado;
Button Circulo;
Button Color;
Button Linea;
private boolean Bcuadrado,Bcirculo,Bcolor=false;
private boolean Blinea=true;
Canvas canvas = new Canvas();
#TargetApi(11)
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout mainLayout =(RelativeLayout)findViewById(R.id.main_layout_id );
View view =getLayoutInflater().inflate(R.layout.itemlayout, mainLayout,false);
mainLayout.addView(view);
mySurfaceView = new MySurfaceView(this);
Cuadrado=(Button)findViewById(R.id.button1);
Circulo=(Button)findViewById(R.id.button2);
Color=(Button)findViewById(R.id.button3 );
Linea=(Button)findViewById(R.id.button4 );
int w= view.getWidth();
int h= view.getHeight();
float x=view.getX();
float y= view.getY();
mySurfaceView.setY(100);
mainLayout.addView(mySurfaceView);
Cuadrado.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(Bcuadrado==false){
Bcuadrado=true;
Bcirculo=false;
Bcolor=false;
Blinea=false;
}
}
});
Circulo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Bcirculo){
Bcuadrado=false;
Bcirculo=true;
Bcolor=false;
Blinea=false;
}
}
});
Color.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Bcolor){
Bcuadrado=false;
Bcirculo=false;
Bcolor=true;
Blinea=false;
}
}
});
Linea.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(!Blinea){
Bcuadrado=false;
Bcirculo=false;
Bcolor=false;
Blinea=true;
}
}
});
}
class MySurfaceView extends SurfaceView{
Path path;
SurfaceHolder surfaceHolder;
volatile boolean running = false;
private Paint paint = new Paint();
float x0=0;
float x1=0;
float y0=0;
float y1=0;
Random random = new Random();
public MySurfaceView(Context context) {
super(context);
surfaceHolder = getHolder();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(android.graphics.Color.WHITE);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(Blinea){
if(event.getAction() == MotionEvent.ACTION_DOWN){
path = new Path();
path.moveTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
path.lineTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_UP){
path.lineTo(event.getX(), event.getY());
}
if(path != null){
canvas = surfaceHolder.lockCanvas();
canvas.drawPath(path, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcuadrado){
if(event.getAction()==MotionEvent.ACTION_DOWN){
x0=event.getX();
y0=event.getY();
}
else if(event.getAction()==MotionEvent.ACTION_UP){
x1=event.getX();
y1=event.getY();
canvas = surfaceHolder.lockCanvas();
canvas.drawRect(x0, y0, x1, y1, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcirculo){
if(event.getAction()==MotionEvent.ACTION_DOWN){
x0=event.getX();
y0=event.getY();
}
else if(event.getAction()==MotionEvent.ACTION_UP){
x1=event.getX();
canvas=surfaceHolder.lockCanvas();
canvas.drawCircle(x0, y0,(x1-x0), paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}else if(Bcolor){
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);
canvas=surfaceHolder.lockCanvas();
paint.setColor(0xff000000 + (r << 16) + (g << 8) + b);
surfaceHolder.unlockCanvasAndPost(canvas);
}
return true;
}
}
}
it seems that there are 2 surfaces to paint, and when you draw in one, the other one disappears.
That is exactly how SurfaceView works - it's double buffered. You need to redraw whole frame each time.
From Android's doc: SurfaceHolder
The content of the Surface is never preserved between unlockCanvas() and lockCanvas(), for this reason, every pixel within the Surface area must be written. The only exception to this rule is when a dirty rectangle is specified, in which case, non-dirty pixels will be preserved.
The canvas does not save what you previously wrote to it. Every time you call unlock(), you must redraw everything all over again.

Categories

Resources