Deletion of canvas bitmap to make background visible - android

I am implementing a code in which i am trying to have a foreground and a background image, i want to erase the foreground image and if i made a mistake i would be able to undo it.
for background i am using an image view and foreground is bitmap on canvas
i have worked this far,
it is erasing the foreground(i.e. the canvas) but undo redo is not working
code is:
public class MainActivity extends AppCompatActivity {
private Bitmap DrawBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint DrawBitmapPaint;
RelativeLayout Rl;
CustomView View;
DrawView drawView;
private Button undo, redo;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.loadActivity();
}
private Paint mPaint;
public class CustomView extends View {
public CustomView(Context c) {
super(c);
create_image();
setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, mPaint);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// mCanvas.drawColor(Color.BLUE);
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
for (Path p : paths){
canvas.drawPath(p, mPaint);
}
setDrawingCacheEnabled(true);
canvas.drawBitmap(DrawBitmap, 0, 0, DrawBitmapPaint);
canvas.drawPath(mPath, mPaint);
canvas.drawRect(mY, 0, mY, 0, DrawBitmapPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
mPath = new Path();
paths.add(mPath);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
// performClick();
invalidate();
break;
}
return true;
}
public void clear() {
create_image();
// Added later..
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
// mCanvas.drawColor(Color.BLUE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(40);
this.invalidate();
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
invalidate();
} else {
}
//toast the user
}
public void onClickRedo() {
if (undonePaths.size() > 0) {
paths.add(undonePaths.remove(undonePaths.size() - 1));
invalidate();
} else {
}
//toast the user
}
}
public void loadActivity() {
undo = (Button) findViewById(R.id.button1);
redo = (Button) findViewById(R.id.button2);
drawView = new DrawView(this);
View = new CustomView(this);
Rl = (RelativeLayout) findViewById(R.id.linearLayout2);
Rl.addView(View);
Bitmap bitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.sample);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
// mCanvas.drawColor(Color.BLUE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(40);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaint.setStrokeWidth(40);
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(40);
undo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View.onClickUndo();
}
});
redo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
View.onClickRedo();
}
});
}
public void create_image() {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int screenWidth = displaymetrics.widthPixels;
int screenHeight = displaymetrics.heightPixels;
DrawBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
Bitmap.Config.ARGB_4444);
mCanvas = new Canvas(DrawBitmap);
Bitmap bitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.sample);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
mCanvas.drawBitmap(bitmap, 0, 0, null);
mPath = new Path();
DrawBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
paths.add(mPath);
}
}
and my layout is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.approduction.drawing.MainActivity">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Undo" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Redo" />
</LinearLayout>
<RelativeLayout
android:id="#+id/linearLayout2"
android:layout_below="#id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#mipmap/ic_launcher"/>
</RelativeLayout>
any suggestions would be valuable
Thanks in advance..

The problem is you have 2 canvas here: canvas and mCanvas.
Your undo/redo works only for canvas and not mCanvas. That's the issue you have. You need to either remove mCanvas in onTouchUp() or alter the code there to implement undo/redo functionality.
Refer my answer here for more info: https://stackoverflow.com/a/38220061/4747587

Related

Android canvas load bmp on click button

i have a layout for drawing content_designer.xml
<Button
android:id="#+id/loadBMP"
android:layout_width="match_parent"
android:layout_height="100dp"
android:text="Load"/>
<com.system.v.construct.Drawing
android:id="#+id/canvasDraw"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
In my activity i set the view and whe user click the button bmp must be loaded.
setContentView(R.layout.content_designer);
Button load=(Button)findViewById(R.id.loadBMP);
final Drawing drawing=new Drawing(this);
load.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"Click",Toast.LENGTH_LONG).show();
drawing.looadBMP();
}
});
In drawing class i have a method looadBMP()
But the image doesnt load, i'm beginner in drawing, so sorry for mistake
Here is a full Drawin class seems like method on Draw is executed first, i need bmp image load on button click:
public class Drawing extends View implements OnTouchListener {
private Canvas mCanvas;
private Path mPath;
public Paint mPaint;
private ArrayList<Path> paths = new ArrayList<Path>();
Bitmap bmp;
public static Canvas myCanvas;
public Drawing(Context context) {
super(context);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
public void looadBMP()
{
setFocusable(true);
setFocusableInTouchMode(true);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.simple);
this.setOnTouchListener(this);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(6);
mCanvas = new Canvas(bmp);
mPath = new Path();
paths.add(mPath);
mCanvas.drawBitmap(bmp, 0, 0, mPaint);
for (Path p : paths) {
mCanvas.drawPath(p, mPaint);
}
}
#Override
protected void onDraw(Canvas canvas) {
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 0;
//Drawing dw = new Drawing();
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath = new Path();
paths.add(mPath);
}
#Override
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}

Erase drawing in canvas

I have written an Android application with a Canvas for drawing with a stylus. It works well. When I'm pushing the upper function key of my stylus I would like to erase the drawing by brushing over the text. The normal drawing is in black, so I thought to do the erase with white (on top of the black line). My problem is that all lines change the color when I press the upper function key of the stylus (i.e. all lines are then white) instead of just painting the new draw line in white.
Another option would be to delete elements from the path for the erase. If somebody has a solution for this, I would be happy too.
The layout looks as follows:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context="StylusBaselineA">
<inf.ethz.ch.affectivestudy.CanvasView
android:id="#+id/baselineACanvas"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="#FFFFFF" />
</android.support.constraint.ConstraintLayout>
The CanvasView class look as follows:
public class CanvasView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Path mPathErase;
Context context;
private Paint mPaint;
private Paint mPaintErase;
private float mX, mY;
private static final float TOLERANCE = 5;
private boolean erase = false;
public CanvasView(Context c, AttributeSet attrs) {
super(c, attrs);
context = c;
// we set a new Path
mPath = new Path();
mPathErase = new Path();
// and we set a new Paint with the desired attributes
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeWidth(4f);
mPaintErase = new Paint();
mPaintErase.setAntiAlias(true);
mPaintErase.setColor(Color.WHITE);
mPaintErase.setStyle(Paint.Style.STROKE);
mPaintErase.setStrokeJoin(Paint.Join.ROUND);
mPaintErase.setStrokeWidth(4f);
}
// override onSizeChanged
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// your Canvas will draw onto the defined Bitmap
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
// override onDraw
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw the mPath with the mPaint on the canvas when onDraw
if (erase) {
canvas.drawPath(mPathErase, mPaintErase);
} else {
canvas.drawPath(mPath, mPaint);
}
}
// when ACTION_DOWN start touch according to the x,y values
private void startTouch(float x, float y) {
if (erase) {
mPathErase.moveTo(x, y);
} else {
mPath.moveTo(x, y);
}
mX = x;
mY = y;
}
// when ACTION_MOVE move touch according to the x,y values
private void moveTouch(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOLERANCE || dy >= TOLERANCE) {
if (erase) {
mPathErase.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
} else {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
}
mX = x;
mY = y;
}
}
public void clearCanvas() {
mPath.reset();
mPathErase.reset();
invalidate();
}
// when ACTION_UP stop touch
private void upTouch() {
if (erase) {
mPathErase.lineTo(mX, mY);
} else {
mPath.lineTo(mX, mY);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (event.getToolType(0) == MotionEvent.TOOL_TYPE_ERASER) {
// Upper function key of stylus
erase = true;
} else if (event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER) {
// Touch input
erase = false;
return false;
} else {
erase = false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
moveTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
upTouch();
invalidate();
break;
}
return true;
}
}
Try this.
public class CanvasActivity extends AppCompatActivity {
private Paint mPaint;
View mView;
Button clear;
private Canvas mCanvas;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_canvas);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.Linear_layout);
mView = new DrawingView(this);
layout.addView(mView, new LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT));
clear= (Button) findViewById(R.id.clear);
clear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCanvas.drawColor(Color.WHITE);
}
});
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.GREEN);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
}
public class DrawingView extends View {
public int width;
public int height;
private Bitmap mBitmap;
private Path mPath;
private Paint mBitmapPaint;
Context context;
private Paint circlePaint;
private Path circlePath;
public DrawingView(Context c) {
super(c);
context=c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
circlePaint = new Paint();
circlePath = new Path();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath( mPath, mPaint);
canvas.drawPath( circlePath, circlePaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
circlePath.reset();
circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
circlePath.reset();
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
}

How can I implement Pencil Shades like hb, 2b, 4b, etc. to draw anything in Canvas of my Android Application?

I need to implement the pencil shades from 9b to 9h with the list showing the shades on pencil button Click() and after clicking the list item, the pencil should change to its new shade. Also need the eraser implementation on erase button click to erase the path drawn by pencil.
This is the code for drawing with a fixed size pen on a canvas without a button click. And the clearCanvas() method is called on button click that clears the whole Canvas.
Any help would be appreciated.
public class MainActivity extends AppCompatActivity {
private CanvasView customCanvas;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customCanvas = (CanvasView) findViewById(R.id.custom_canvas);
toolbar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(toolbar);
assert getSupportActionBar()!=null;
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void onClick(View view){
customCanvas.clearCanvas();
}
}
public class CanvasView extends View{
public int width;
public int height;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
Context context;
private Paint mPaint, mErase;
private float mX, mY;
private static final float TOLERANCE = 5;
private boolean erase=false;
public CanvasView(Context c, AttributeSet attrs) {
super(c, attrs);
// we set a new Path
mPath = new Path();
// and we set a new Paint with the desired attributes
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4f);
}
// override onSizeChanged
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// your Canvas will draw onto the defined Bitmap
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
// override onDraw
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw the mPath with the mPaint on the canvas when onDraw
canvas.drawPath(mPath, mPaint);
}
// when ACTION_DOWN start touch according to the x,y values
private void startTouch(float x, float y) {
mPath.moveTo(x, y);
mX = x;
mY = y;
}
// when ACTION_MOVE move touch according to the x,y values
private void moveTouch(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOLERANCE || dy >= TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
// Clear Canvas
public void clearCanvas(){
mPath.reset();
invalidate();
}
// when ACTION_UP stop touch
private void upTouch() {
mPath.lineTo(mX, mY);
}
//override the onTouchEvent
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
moveTouch(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
upTouch();
invalidate();
break;
}
return true;
}
}
XML file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/actionBar"
layout="#layout/action_bar" />
<View
android:layout_below="#+id/actionBar"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#2084AF" />
<com.admin.mainactivity.CanvasView
android:layout_below="#+id/actionBar"
android:id="#+id/custom_canvas"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

Creating a pen/eraser drawing app with background. Eraser erases background image, it should only erase pen

I followed the fingerpaint code and some other code to create an app that allows you to draw onto the screen, with a background image in place to draw over top of. In addition, I'd like to make an eraser tool that erases just the pen, not the background image. I think I have to use two canvases for this, but couldn't figure out how it would work with Canvas' onDraw.
Here's my code. Right now pen drawing works, and eraser drawing erases but it erases the background image. I only want it to erase the pen.
If you could give me hints on what to do I would really appreciate it.
===
//MainActivity.java
public class MainActivity extends Activity implements OnClickListener {
public MyView myView;
boolean penOn;
boolean eraserOn;
Bitmap bMap;
private Canvas mCanvas;
private Canvas myForegroundCanvas;
private Path mPath;
private Bitmap mBitmap;
private Paint mPaint, mBitmapPaint;
private ArrayList<DrawAction> paths = new ArrayList<DrawAction>();
private ArrayList<DrawAction> undonePaths = new ArrayList<DrawAction>();
int selectedColor=Color.RED;
RelativeLayout container;
private int width;
private int height;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View mainView = getLayoutInflater().inflate(R.layout.activity_main,
null);
myView = new MyView(this);
container = (RelativeLayout) mainView.findViewById(R.id.container);
container.addView(myView);
setContentView(mainView);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(16);
Button pen = (Button) mainView.findViewById(R.id.buttonpen);
pen.setOnClickListener(this);
Button eraser = (Button) mainView.findViewById(R.id.buttonerase);
eraser.setOnClickListener(this);
pen.bringToFront();
eraser.bringToFront();
}
public class MyView extends View {
public MyView(Context c) {
super(c);
if (android.os.Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
DisplayMetrics displaymetrics = new DisplayMetrics();
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
MainActivity.this.width = size.x;
MainActivity.this.height = size.y;
bMap = getBitmapFromAsset(MainActivity.this, "google.png");
Bitmap background = Bitmap.createScaledBitmap(bMap,
MainActivity.this.width, MainActivity.this.height, false);
mBitmap = background.copy(Bitmap.Config.ARGB_8888, true);
mCanvas = new Canvas(mBitmap);
myForegroundCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
Paint textPaint = new Paint();
textPaint.setTextSize(40);
final Iterator<DrawAction> i = paths.iterator();
while (i.hasNext()) {
final DrawAction d = i.next();
if (d.type.equals("pen")) {
mPaint.setColor(d.color);
mPaint.setXfermode(null);// clear the draw
canvas.drawPath(d.path, mPaint);
// myForegroundCanvas.drawPath(d.path, mPaint);
} else if (d.type.equals("eraser")) {
// mPaint.setAlpha(0xFF);//transperent color
mPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));// clear the draw
canvas.drawPath(d.path, mPaint);
// myForegroundCanvas.drawPath(d.path, mPaint);
}
}
mPaint.setColor(selectedColor);
canvas.drawPath(mPath, mPaint);
// canvas.drawCanvas(myForegroundCanvas, 0, 0, null);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
DrawAction d = new DrawAction(mPath, Color.RED);
paths.add(d);
mPath = new Path();
}
private void touch_start_eraser(float x, float y) {
undonePaths.clear();
mPaint.setColor(Color.WHITE);
selectedColor=Color.WHITE;
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move_eraser(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up_eraser() {
mPath.lineTo(mX, mY);
DrawAction d = new DrawAction(mPath, true);
paths.add(d);
mPath = new Path();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if ( !penOn && eraserOn) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start_eraser(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move_eraser(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up_eraser();
invalidate();
break;
}
return true;
} else {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
}
public Bitmap getBitmapFromAsset(Context context, String strName) {
AssetManager assetManager = context.getAssets();
InputStream istr;
Bitmap bitmap = null;
try {
istr = assetManager.open(strName);
bitmap = BitmapFactory.decodeStream(istr);
} catch (IOException e) {
return null;
}
return bitmap;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonpen:
penOn=true;
eraserOn=false;
break;
case R.id.buttonerase:
penOn=false;
eraserOn=true;
break;
}
}
}
===
//DrawAction.java, a helper class for holding the path and what type of drawing to do (pen or erase)
public class DrawAction {
public String type;
public Path path;
public int color;
public DrawAction(final Path p, final int color) {
this.type="pen";
this.path=p;
this.color=color;
}
public DrawAction(final Path p, final boolean isEraser) {
this.type="eraser";
this.path=p;
}
}
====
//activity_main.xml the layout code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.doodle5.MainActivity"
tools:ignore="MergeRootFrame" >
<Button
android:id="#+id/buttonpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_marginTop="50dp"
android:text="Pen" />
<Button
android:id="#+id/buttonerase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="25dp"
android:layout_marginTop="50dp"
android:text="Erase" />
</RelativeLayout>
I figured it out. I ended up placing the background image as a background drawable on the container, and not drawing it onto the canvas.
In onDraw I commented out this line:
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
In onCreate I added:
BitmapDrawable ob = new BitmapDrawable(backgroundBitmap);
container.setBackgroundDrawable(ob);

Draw with canvas Android

For now I want the canvas to just draw a color.
public class AndroidTentaTestActivity extends Activity {
private Bitmap bm;
private Canvas c;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
bm = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
c = new Canvas(bm);
c.drawARGB(100, 0, 0, 150);
}
}
The code above is what I´ve written so far that obviously does not work. I suspect the Bitmap is somehow not connected to what I am doing but I don´t know how to fix it. How do I?
Change the desired color in mPaint.setColor().
public class AndroidTentaTestActivity extends AppCompatActivity {
MyView mv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mv = new MyView(this);
mv.setDrawingCacheEnabled(true);
setContentView(mv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
}
private Paint mPaint;
#Override
public void onClick(View v) {
}
public class MyView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
Context context;
public MyView(Context c) {
super(c);
context = c;
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(0xFFFFFFFF);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 1;
private void touch_start(float x, float y) {
//showDialog();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
// mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); //2,2.old values
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
LinearLayout ll = (LinearLayout) findViewById(R.id.rect);
Paint paint = new Paint();
paint.setColor(Color.parseColor("#CD5C5C"));
Bitmap bg = Bitmap.createBitmap(ll.getWidth(),ll.getHeight() , Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bg);
canvas.drawARGB(200, 0, 225, 255);
ll.setBackgroundDrawable(new BitmapDrawable(bg));

Categories

Resources