How to work with finger eraser in android? - android

I have prepared one paint app.In my app we can draw any thing.It is working fine.Here i want prepare finger erase for erase paint.Eraser is working,but it is eraser all the drawn paint.I want to eraser only where i touch if drawn paint is there for that i wrote some code,
this my ondraw method,
public void onDraw(Canvas canvas) {
if (myDrawBitmap == null) {
myDrawBitmap = Bitmap.createBitmap(480, 800,
Bitmap.Config.ARGB_8888);
mBmpDrawCanvas = new Canvas(myDrawBitmap);
mIntDrawArray = new int[myDrawBitmap.getWidth()
* myDrawBitmap.getHeight()];
}
if (mBmpDrawCanvas != null) {
myDrawBitmap.getPixels(mIntDrawArray, 0, myDrawBitmap.getWidth(),
0, 0, myDrawBitmap.getWidth(), myDrawBitmap.getHeight());
for (Path path : ILearnPaintActivity.mArryLstPath) {
if (ILearnPaintActivity.mArryLstPath.contains(path)
&& ILearnPaintActivity.paintAndEraserFlag == 1) {
mPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
mBmpDrawCanvas.drawPath(ILearnPaintActivity.mPath, mPaint);
} else {
mBmpDrawCanvas.drawPath(ILearnPaintActivity.mPath, mPaint);
}
}
if (myDrawBitmap != null)
canvas.drawBitmap(myDrawBitmap, 0, 0, null);
}
}
draw paint is working fine.In same activity i have one button "Eraser". when we click on eraser button i assign flag for difference.Please help me how to do this...

first u need to make clear what erase.
for vector base canvas it's delete vector element.
for pixel base canvas it's mean draw with backgournd color. (or make it's transparency)
so in my point of view. when erase. you can change a Paint with backgournd color. and continue draw a very bold line on bitmap by touch.

try like this
mBitmap.eraseColor(Color.TRANSPARENT); // Bitmap erase color
mPath.reset(); // your path
mView.invalidate(); // your View Path

Related

How to prevent Eraser from Removing Bitmap?

How to prevent Eraser from Removing Bitmap or Paint Must Draw in Back Side of Image As per Attach Image & My code is as below in Android Java
In Paint View - onDraw my code is as Below
protected void onDraw(Canvas canvas) {
if (mClear) // clear canvas and reset image stack
{
// mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
// mCanvas = new Canvas(mBitmap);
// mCanvas.drawColor(mBackgroundColor);
// mImages.clear();
// mUndoneImages.clear();
// mImages.push(new Image(mBitmap));
// mPath.reset();
// mClear = false;
// return;
}
if (mEraseMode) // if we want to erase, set color of the brush to background color and width to the value chosen with slider
{
mBrushColor = mEraserColor;
mStrokeWidth = mEraserWidth;
} else // if we exit erase mode go back to old width and color
{
mBrushColor = mOldBrushColor;
mStrokeWidth = mOldStrokeWidth;
}
// draw current path
mPaint.setColor(mBrushColor);
mPaint.setStrokeWidth(mStrokeWidth);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); // draw the main bitmap on canvas
mCanvas.drawPath(mPath, mPaint);
}
I want to Draw Image(Bitmap) Like Below
Here Eraser Should not Remove the Image (Black color Not Remove)
Eraser & Paint Must work like this

canvas draw not smooth circles

At the first of my game, I draw some circles from alpha 0 to 255 using canvas(it's like making a fade_in animation by myself)
But if you see in picture(this picture captured in alpha 230),from alpha 0 to 254 these circles aren't smooth!(click on picture to see what I mean)
(and only when alpha become 255 the circles become smooth)
What's the problem and how can I fix this?
my code:
I have a game loop, that get canvas
canvas = gameView.getHolder().lockCanvas();
then in my view ,at first I set :
paintAlpha = 0;
paint = new Paint();
paint.setAntiAlias(true);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setAlpha(paintAlpha);
paint.setColor(Color.parseColor(color));
then in every loop(every ticks) I do this:
if(paintAlpha < 255) {
paintAlpha+=1;
paint.setAlpha(paintAlpha);
}
canvas.drawCircle(cx, cy, currentRadius, paint);
Solution:
Thanks to #nitesh.
The problem was because of surfaceView that can't set anti alias to canvas (in View you don't have this problem ,I don't know why)
By using Bitmap and draw on it and finally draw bitmap by canvas , the problem solved (instead of drawing on canvas directly)
Set the following property to paint object
paint.setAntiAlias(true);
For better understanding and other approaches refer this link
https://medium.com/#ali.muzaffar/android-why-your-canvas-shapes-arent-smooth-aa2a3f450eb5#.p9iktozdi
From the article
Draw a bitmap first if:
- You need to persist the image.
- You need to draw transparent pixels.
- Your shapes don’t change often and/or require time consuming operations.
Use anti-aliasing to draw smooth edges.
Avoid redraws on the bitmap if possible or else, clear a bitmap before redrawing.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bitmap == null) {
bitmap = Bitmap.createBitmap(200,
200,
Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);
}
bitmapCanvas.drawColor(
Color.TRANSPARENT,
PorterDuff.Mode.CLEAR); //this line moved outside if
drawOnCanvas(bitmapCanvas);
canvas.drawBitmap(bitmap, mLeftX, mTopY, p);
}
protected void drawOnCanvas(Canvas canvas) {
canvas.drawCircle(mLeftX + 100, mTopY + 100, 100, p);
}
you can approach this by
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
or
paint.setAntiAlias(true);

Canvas bitmap is not being saved

i am new to android canvas and i failed to get solution of my problem,
the problem is:
I am using canvas in two modes AvoidXfermode.Mode.TARGET(to remove occurence of a single color) and PorterDuff.Mode.CLEAR(to erase a part of my canvas).
everything independently is working perfect
but in my code i want to use both of them in such a way that when i choose i want to erase a particular color it should erase it, and my code is doing so,
but after removing that particular color when i am switching my mode to eraser mode...everything which was deleted using AvoidXfermode comes back.
i am doing these things on a bitmap,
my onDraw method is:
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(DrawBitmap, 0, 0, DrawBitmapPaint);
if (flag != 1) {
setDrawingCacheEnabled(true);
for (Path p : paths) {
canvas.drawPath(p, mPaint);
Bitmap bitmap = getDrawingCache();
DrawBitmap = bitmap;
//
}
//canvas.setBitmap(bitmap.isMutable() ? bitmap : bitmap.copy(Bitmap.Config.ARGB_8888,true));
} else if (flag == 1) {
if (touchx > mCanvas.getWidth() || touchy > mCanvas.getHeight() || touchx < 0 || touchy < 0) {
return;
}
for (Path p : paths) {
color = DrawBitmap.getPixel(touchx, touchy);
mPaint.setXfermode(new AvoidXfermode(color, 100, AvoidXfermode.Mode.TARGET));
mPaint.setColor(Color.TRANSPARENT);
canvas.drawPaint(mPaint);
setDrawingCacheEnabled(true);
Bitmap bitmap = getDrawingCache();
DrawBitmap = bitmap;
}
}
}
everything is declared in onDraw for now just for the this question,
and the code where i switch my mode is:
case R.id.erase:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaint.setColor(Color.TRANSPARENT);
mPaint.setStrokeWidth(40);
flag = 0;
break;
case R.id.DELETE:
flag = 1;
break;
the code where i am creating my canvas is:
DrawBitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.sample);
DrawBitmap = DrawBitmap.copy(Bitmap.Config.ARGB_8888, true);
mCanvas = new Canvas(DrawBitmap);
mPath = new Path();
paths.add(mPath);
DrawBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
i am wrong somewhere,but i don't know where, any suggestions would be helpful, thanks in advance.
Bitmap bitmap = getDrawingCache();
DrawBitmap = bitmap;
Your logic is a lot complicated. I specifically mean the above lines of code. You have mCanvas that is backed up with the DrawBitmap bitmap. Then you have the canvas of onDraw() which is backed by it's own bitmap. The thing you need to understand is whatever you draw in DrawBitmap stays or as you would call it "saved". Anything that is drawn via canvas is subjected to change during the next call to onDraw().
So if you want to save something in DrawBitmap use the mCanvas. The moment you want to save the state of the user's drawing, draw it in mCanvas. You could just draw everything on mCanvas and at the end of onDraw(), you can call canvas.drawBitmap(DrawBitmap, 0, 0, DrawBitmapPaint); This way everything that is done by the user is saved every step of the way.

View background not drawn correctly

I'm trying to create a view that draws a background colour with an image on top of it. The image should be transformed by a matrix. The background should not be.
The onDraw() method looks like this:
protected void onDraw(Canvas canvas) {
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
Drawable drawable = getImageDrawable();
if (drawable == null) {
return;
}
int count = canvas.save();
if (clipRect != null) {
canvas.clipRect(clipRect);
}
canvas.concat(matrix);
drawable.draw(canvas);
canvas.restoreToCount(count);
}
On some of the devices I've tested on, the background above and to the left of the image is not drawn correctly. See video here:
https://youtu.be/rno2XxaeNUA You'll need to pause the video to see what's going on.
This problem was caused by accidentally overriding View.getMatrix()

android: paths to become part of the bitmap when requested

I am learning on canvas and bitmap with paths and currently working on a drawing app where user can draw paths freely on the extended view.
The app also allow allowing user to import bitmap as the background and draw on it.
Extending the View named DoodleView:
public DoodleView(Context context, AttributeSet attrs)
{
super(context, attrs); // pass context to View's constructor
this.context_new=context;
setFocusable(true);
setFocusableInTouchMode(true);
} // end DoodleView constructor
onDraw:
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, null);
for (Path p : paths)
{
paintLine.setColor(colorsMap.get(p));
canvas.drawPath(p, paintLine);
}
paintLine.setColor(selectedColor);
canvas.drawPath(mPath, paintLine);
if (ConvertCanvasToBitmap == true)
{
canvas.drawBitmap(bitmap, 0, 0, paintLine);
ConvertCanvasToBitmap = false;
}
}
FlipHorizontally:
public void flipImageHorizontally()
{
ConvertCanvasToBitmap = true;
invalidate();
Matrix flipHorizontalMatrix = new Matrix();
flipHorizontalMatrix.setScale(-1,1);
flipHorizontalMatrix.postTranslate(bitmap.getWidth(),0);
Bitmap HorizontalFlipped = Bitmap.createBitmap
(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipHorizontalMatrix, true);
bitmap = HorizontalFlipped;
invalidate();
}
Question:
My goal is that for the paths that are already drawn, when the user tries to flip the image, the paths drawn would also be flipped. (i.e. the paths become part of the image already, and user are disallows to undo the paths anymore).
However, I have tested using the above codes, when the flip button is pressed, the bitmap background can be flipped, yet the drawn would disappear. And then when further drawn on it, the paths will appear again, but stay unflipped.
In short, how to make the paths to become part of the bitmap when the flip button is pressed?
Thanks!
Edit:
Based on the Android 2.1 View's getDrawingCache() method always returns null, I have modified the onDraw with the following code, but got
02-22 21:38:34.685: E/AndroidRuntime(18617): java.lang.NullPointerException
02-22 21:38:34.685: E/AndroidRuntime(18617): at android.graphics.Bitmap.createBitmap(Bitmap.java:455)
02-22 21:38:34.685: E/AndroidRuntime(18617): at com.pearmak.drawing.DoodleView.onDraw(DoodleView.java:148)
Modified code:
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, null); // draw the background screen
for (Path p : paths)
{
paintLine.setColor(colorsMap.get(p));
paintLine.setStrokeWidth(widthMap.get(p));
canvas.drawPath(p, paintLine);
}
paintLine.setColor(selectedColor);
paintLine.setStrokeWidth(selectedWidth);
canvas.drawPath(mPath, paintLine);
if (ConvertCanvasToBitmap == true)
{
//Method 1
// RelativeLayout page = (RelativeLayout) findViewById(R.id.doodleView);
// Bitmap screenshot = Bitmap.createBitmap(page.getWidth(), page.getHeight(), Config.ARGB_8888);
// bitmap = screenshot;
// ConvertCanvasToBitmap = false;
//Method 2
Bitmap screenshot2;
layout(0, 0, DoodlzViewWidth, DoodlzViewHeight);
setDrawingCacheEnabled(true);
screenshot2 = Bitmap.createBitmap(getDrawingCache()); // LINE 148
setDrawingCacheEnabled(false);
bitmap = screenshot2;
}
}
you need to create the bitmap from that view
please refer to drawingcache like here
Android 2.1 View's getDrawingCache() method always returns null
now try to flip this bitmap

Categories

Resources