I am working a project in which an erasing functionality is there I want to user can undo
his erasing if he want but this functionality is not working for me.
My code is as:-
public EraserView(Context context) {
super(context);
setFocusable(true);
setBackgroundResource(R.drawable.back);
// setting paint
mPaint = new Paint();
mPath = new Path();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setColor(Color.TRANSPARENT);
mPaint.setAntiAlias(true);
// getting image from resources
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.drawable.image2);
// converting image bitmap into mutable bitmap
bitmap = bm.createBitmap(295, 260, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
pcanvas.drawBitmap(bm, 0, 0, null);
paths.add(mPath);
}
#Override
protected void onDraw(Canvas canvas) {
// draw a circle that is erasing bitmap
pcanvas.drawCircle(x,y,r,mPaint);
/*for (Path objpath : paths) {
pcanvas.drawPath(objpath, mPaint);
}*/
canvas.drawBitmap(bitmap, 0, 0, null);
setBitmap(bitmap);
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
case MotionEvent.ACTION_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
case MotionEvent.ACTION_MOVE:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
case MotionEvent.ACTION_POINTER_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 8;
// Atlast invalidate canvas
invalidate();
break;
}
return true;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
public void onClickUndo () {
if (paths.size()>0)
{
paths.add(paths.remove(paths.size()-1));
invalidate();
}
else
{
}
}![enter image description here][1]
as shown in image we erase some part of dog after that click undo button dog should come in his initial position.please any one guide me.
Have you tried saving (Canvas.save()) the Canvas before erasing any portion of the bitmap and then restoring (Canvas.restore()) and redrawing once the button is clicked?
Related
I am just creating an application in which I need to drill into the bitmap, I succeed for that also but bitmap drill is lagging as I touch image view. Any help on this is really appreciated...Thanks..
Here is Main File
public class MainActivity extends Activity{
int x, y;
Bitmap background,foreground;
ImageView iv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.img);
background = BitmapFactory.decodeResource(getResources(), R.mipmap.mug_shot);
foreground = BitmapFactory.decodeResource(getResources(), R.mipmap.poster);
iv.setImageBitmap(combineTwoBitmaps(background, foreground));
iv.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View view, MotionEvent event)
{
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
x = (int) (event.getRawX()+100);
y = (int) (event.getY()+100);
System.out.println("X : "+ x +" Y : "+ y);
foreground = punchAHoleInABitmap(foreground);
iv.setImageBitmap(combineTwoBitmaps(background,foreground));
System.out.println("Hello this is Test2");
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
});
}
private Bitmap punchAHoleInABitmap(Bitmap foreground)
{
System.out.println("Hello this is Tesyt");
Bitmap bitmap = Bitmap.createBitmap(foreground.getWidth(), foreground.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
canvas.drawBitmap(foreground, 0, 0, paint);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
float radius = (float)(getScreenSize().x *.35);
float x1 = (float) ((x*.5) + (radius * .5));
float y1 = (float) ((y*.5) + (radius * .5));
System.out.println("X1 : "+ x1 +" Y1 : "+ y1);
canvas.drawCircle(x1, y1, 50, paint);
return bitmap;
}
private Bitmap combineTwoBitmaps(Bitmap background, Bitmap foreground) {
Bitmap combinedBitmap = Bitmap.createBitmap(background.getWidth(), background.getHeight(), background.getConfig());
Canvas canvas = new Canvas(combinedBitmap);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(background, 0, 0, paint);
canvas.drawBitmap(foreground, 0, 0, paint);
return combinedBitmap;
}
private Point getScreenSize() {
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
}
ACTION_MOVE is called many times when users slide the screen. This means you will create quite amount of bitmaps in short time.
With GestureDetector you can detect exact one slide/swipe/fling.
i am developing an app in android where on moving finger erase functionality is used.
in my app erasing feature is working properly but when we switch to next activity the erasing area appears black. please give any suggestion or link to remove this problem thanx in advance..
my code is
class EraseView extends View{
Bitmap bgr,bgr1;
Bitmap overlayDefault;
Bitmap overlay;
Paint pTouch;
int X = -100;
int Y = -100;
Canvas c2;
GlobalVariable globalVariable;
#SuppressLint("NewApi")
public EraseView(Context context,Bitmap bitmap) {
super(context);
globalVariable=(GlobalVariable)context.getApplicationContext();
bgr = BitmapFactory.decodeResource(getResources(),R.drawable.erase_bg);
bgr1 = BitmapFactory.decodeResource(getResources(),R.drawable.erase_bg);
overlayDefault =bitmap;
overlayDefault = Bitmap.createScaledBitmap(overlayDefault,globalVariable.bitmap_width, globalVariable.bitmap_height, true);
overlay = bitmap.copy(Config.ARGB_8888, true);
overlay = Bitmap.createScaledBitmap(overlay, globalVariable.bitmap_width, globalVariable.bitmap_height, true);
c2 = new Canvas(overlay);
pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
pTouch.setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
pTouch.setColor(Color.TRANSPARENT);
pTouch.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL));
globalVariable.bitmapArray=new ArrayList<Bitmap>();
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_MOVE: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_UP:
globalVariable.count++;
globalVariable.bitmapArray.add(globalVariable.bitmap);
break;
}
return true;
}
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
/*//draw background
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(bgr, 0, 0, null);
//copy the default overlay into temporary overlay and punch a hole in it
c2.drawBitmap(overlayDefault, 0, 0, null); //exclude this line to show all as you draw
c2.drawCircle(X, Y, 80, pTouch);
//draw the overlay over the background
canvas.drawBitmap(overlay, 0, 0, null);*/
canvas.drawColor(Color.TRANSPARENT);
Paint new_paint = new Paint(/*Paint.ANTI_ALIAS_FLAG*/);
new_paint.setXfermode(new PorterDuffXfermode(Mode.SRC_ATOP));
canvas.drawBitmap(bgr, 0, 0, new_paint);
c2.drawCircle(X, Y, 25, pTouch);
canvas.drawBitmap(overlay, 0, 0, new_paint);
Bitmap tempBitmap = Bitmap.createBitmap(globalVariable.bitmap_width,globalVariable.bitmap_height, Bitmap.Config.RGB_565);
Canvas can=new Canvas(tempBitmap);
can.drawBitmap(bgr, 0, 0, null);
can.drawBitmap(overlay, 0, 0, null);
globalVariable.bitmap=tempBitmap;
}
}
In above question after erasing image erasing area appears black in next activity..
for this you replace this code by below code
Bitmap tempBitmap = Bitmap.createBitmap(globalVariable.bitmap_width,globalVariable.bitmap_height, Bitmap.Config.RGB_565);
in this if u set this code then definetly you find erasing area transparent..
Bitmap tempBitmap = Bitmap.createBitmap(globalVariable.bitmap_width,globalVariable.bitmap_height, Bitmap.Config.ARGB_8888);
I am making an app in which I am drawing a bitmap on a canvas as a overlay after erasing some part of overlay bitmap I want to save it into sd-card but when is save it contain black
UI like attach screen
And My code is bellow:-
public EraserView(Context context) {
super(context);
setFocusable(true);
setBackgroundResource(R.drawable.back);
// setting paint
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setColor(Color.TRANSPARENT);
mPaint.setAntiAlias(true);
Resources r = this.getContext().getResources();
Bitmap bm = BitmapFactory.decodeResource(getResources(),
R.drawable.image2);
bitmap = bm.createBitmap(295, 260, Config.ARGB_8888);
pcanvas = new Canvas();
pcanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
pcanvas.drawBitmap(bm, 0, 0, null);
}
#Override
protected void onDraw(Canvas canvas) {
pcanvas.drawCircle(x, y, r, mPaint);
canvas.drawBitmap(bitmap, 0, 0, null);
setBitmap(bitmap);
super.onDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
r = 2;
invalidate();
break;
case MotionEvent.ACTION_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 20;
invalidate();
break;
case MotionEvent.ACTION_MOVE:
x = (int) event.getX();
y = (int) event.getY();
r =2;
invalidate();
break;
case MotionEvent.ACTION_POINTER_UP:
x = (int) event.getX();
y = (int) event.getY();
r = 2;
// Atlast invalidate canvas
invalidate();
break;
}
return true;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public Bitmap getBitmap() {
return bitmap;
}
But My requirement is only save overlay thanks in advance.
When CompressFormat is JPEG its shows you black background because JPEG format does not support alpha transparency, just change CompressFormat to PNG and even save your image in png format instead jpeg. check below code:
ByteArrayOutputStream objbytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, objbytes);
While delcare path of image, use .png extension.
directory + "/pics+"+System.currentTimeMillis()+".png";
I am creating a drawing app that utilizes the DrawingSurfaceView class below. In that class i have a Paint Called eraserPaint that the user can toggle on and off.. When on that paint is suppose to eraser what ever is in its path. but instead its just drawing a black line..
When i save out the canvas as a transparent png the eraser is correct but on the screen it shows black..
Screenshot from phone of EraserPaint used to write "Erik" on blob
Saved out PNG from canvas
eraserPaint looks like this:
eraserPaint = new Paint();
eraserPaint.setAlpha(0);
eraserPaint.setColor(Color.TRANSPARENT);
eraserPaint.setStrokeWidth(60);
eraserPaint.setStyle(Style.STROKE);
eraserPaint.setMaskFilter(null);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
eraserPaint.setAntiAlias(true);
the WHOLE class
public KNDrawingSurfaceView(Context c, float width, float height, KNSketchBookActivity parent) {
super(c);
myWidth = width;
myHeight = height;
mBitmap = Bitmap.createBitmap((int) myWidth, (int) myHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
_parent = parent;
mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);
tile = new Paint();
tileImage = BitmapFactory.decodeResource(getResources(), R.drawable.checkerpattern);
shader = new BitmapShader(tileImage, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
tile.setShader(shader);
mPath = new Path();
eraserPaint = new Paint();
eraserPaint.setAlpha(0x00);
eraserPaint.setColor(Color.TRANSPARENT);
eraserPaint.setStrokeWidth(60);
eraserPaint.setStyle(Style.STROKE);
//eraserPaint.setMaskFilter(null);
eraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
eraserPaint.setAntiAlias(true);
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mCanvas.drawRect(0, 0, myWidth, myHeight, tile);
mCanvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
if (!_parent.isDrawerOpen()&&mPaint!=null) {
Log.v("onDraw:", "curent paths size:" + paths.size());
//mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
//canvas.drawPath(mPath, mPaint);
for (int i=0;i< paths.size();i++) {
tempPaint = paints.get(i);
eraserPaint.setStrokeWidth(tempPaint.getStrokeWidth());
if(fills.get(i)){
tempPaint.setStyle(Style.FILL_AND_STROKE);
eraserPaint.setStyle(Style.FILL_AND_STROKE);
}else{
tempPaint.setStyle(Style.STROKE);
eraserPaint.setStyle(Style.STROKE);
}
if(erasers.get(i)){
//tempPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPath(paths.get(i), eraserPaint);
}else{
//tempPaint.setXfermode(null);
canvas.drawPath(paths.get(i), tempPaint);
}
//canvas.drawPath(paths.get(i), tempPaint);
}
if(_parent.toggleFill.isChecked()){
mPaint.setStyle(Style.FILL_AND_STROKE);
eraserPaint.setStyle(Style.FILL_AND_STROKE);
}else{
mPaint.setStyle(Style.STROKE);
eraserPaint.setStyle(Style.STROKE);
}
if(_parent.toggleErase.isChecked()){
//mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawPath(mPath, eraserPaint);
}else{
//mPaint.setXfermode(null);
canvas.drawPath(mPath, mPaint);
}
//canvas.drawPath(mPath, mPaint);
}
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
undonePaints.add(paints.remove(paints.size() - 1));
undoneFills.add(fills.remove(fills.size() - 1));
undoneErasers.add(erasers.remove(erasers.size() - 1));
clearCanvasCache();
invalidate();
} else {
}
_parent.checkButtonStates();
}
public void onClickRedo() {
if (undonePaths.size() > 0) {
paths.add(undonePaths.remove(undonePaths.size() - 1));
paints.add(undonePaints.remove(undonePaints.size() - 1));
fills.add(undoneFills.remove(undoneFills.size() - 1));
erasers.add(undoneErasers.remove(undoneErasers.size() - 1));
clearCanvasCache();
invalidate();
} else {
}
_parent.checkButtonStates();
}
public void onClickClear() {
paths.clear();
paints.clear();
fills.clear();
erasers.clear();
undoneFills.clear();
undonePaths.clear();
undonePaints.clear();
undoneErasers.clear();
clearCanvasCache();
invalidate();
_parent.checkButtonStates();
}
public void saveDrawing() {
FileOutputStream outStream = null;
String fileName = "tempTag";
try {
outStream = new FileOutputStream("/sdcard/" + fileName + ".png");
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private void touch_start(float x, float y) {
undonePaths.clear();
undonePaints.clear();
undoneFills.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);
// commit the path to our offscreen
if(_parent.toggleErase.isChecked()){
mCanvas.drawPath(mPath, eraserPaint);
erasers.add(true);
paints.add(eraserPaint);
}else{
mCanvas.drawPath(mPath, mPaint);
erasers.add(false);
paints.add(mPaint);
}
// kill this so we don't double draw
paths.add(mPath);
if(_parent.toggleFill.isChecked()){
fills.add(true);
}else{
fills.add(false);
}
if(_parent.toggleErase.isChecked()){
erasers.add(true);
}else{
erasers.add(false);
}
_parent.checkButtonStates();
mPath = new Path();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(mPaint==null &&!_parent._showingAlert){
_parent.showNoPaintAlert();
}
if (!_parent.isDrawerOpen()&&mPaint!=null) {
float x = event.getX();
float y = event.getY();
if (x > myWidth) {
x = myWidth;
}
if (y > myHeight) {
y = myHeight;
}
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;
} else {
return true;
}
}
public void clearCanvasCache() {
mBitmap = Bitmap.createBitmap((int) myWidth, (int) myHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
}
I should add that i am adding this Custom View to a relative layout that has that checkered pattern as the background image..
PLEASE PLEASE PLEASE help.. i need that preview image to NOT show black after an eraser paint was used.. i need it to show the checkered pattern behind.. I know the eraser is working as those black eraser marks save out as transparent.
NEW NOTE
I was playing around and discovered something else thats curious. Experimenting, i tried switching from drawing to the canvas as passed to the onDraw method and directly to the canvas i set up in the contructor called mCanvas and noticed it did not draw as far as i could see.. so I added a log to the onDraw like so:
protected void onDraw(Canvas canvas) {
Log.v("DRAWING SURFACE", "canvas:"+canvas+" mCanvas:"+mCanvas);
which spits out
06-21 11:10:43.994: V/DRAWING SURFACE(4532): canvas:android.view.Surface$CompatibleCanvas#42a8c030 mCanvas:android.graphics.Canvas#431df180
I had this same problem with my app. I even tried the "finger paint" example code and still had the same problem. I was never able to have the eraser work as a path, but I was able to find a workaround. Rather than drawing a path when I erase, I draw a circle (It could be any shape) when the user puts his finger down or there is a "move" event:
case MotionEvent.ACTION_DOWN:
mPaint.setStrokeWidth(25);
mPaint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
mCanvas.drawCircle(x, y, 10, mPaint);
isErase = true;
invalidate();
}
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
if(isErase)
{
mCanvas.drawCircle(x, y, 20, mPaint);
}
else{
touch_move(x, y);
}invalidate();
break;
It will take some time to incorporate this into your code, but I guarantee you it will take less time than the amount of time you have already spent trying to fix this problem. I can send you more of my PaintView if you think it would be helpful.
Same problem encountered, tried all other solutions found, no luck.
But I got a workaround. You can add a bitmap to store the strokes.
public void init(int width, int height) {
Log.i(TAG,"init with "+width+"x"+height);
foreground = Bitmap.createBitmap(width, height, Config.ARGB_8888);
cacheCanvas = new Canvas();
cacheCanvas.setBitmap(foreground);
}
Whenever there is any touch, record the stroke with the current paint and current stroke width. (the paint could be any color, including the eraser paint)
And then override the onDraw(Canvas) method. As the bitmap supports eraser while the canvas doesn't, we can first draw the resultant image on the bitmap first, and then draw the bitmap to the canvas.
#Override
protected void onDraw(Canvas canvas) {
// Log.i(TAG,"onDraw called");
synchronized (strokes) {
if (strokes.size() > 0) {
for (Stroke s : strokes) {
cacheCanvas.drawPath(s.path, s.color);
}
canvas.drawBitmap(foreground, 0, 0, null);
strokes.clear();
}
}
}
FYI, if the foreground bitmap is very large, the performance will be low. To solve this, we should invalidate only the area which the latest finger touches altered.
This is just a guess: it could be related to hardware acceleration. Try to disable hardware acceleration. If that helps, you can create a bitmap the size of the view, draw all your stuff to that bitmap, and then draw the bitmap into the view's canvas.
For the canvas to erase and invalidate, you have to set the setXfermode of your canvas to null. check the last line of the code.
if(view.getId()==R.id.erase_btn) {
erase_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onDraw.setErase(true);
}
}
}
public void setErase(boolean isErase){
erase=isErase;
if(erase) drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
else drawPaint.setXfermode(null);
}
You can use a boolean variable while choosing eraser (ie. isEraser = true) and in onDraw(), you can draw path if it's not eraser.
#Override
protected void onDraw(Canvas canvas) {
if(!isEraser ){
canvas.drawPath(mPath, mPaint);
}
}
i have two bitmap in my project what i need is that i need to combine those two bit map and combine those bit map to a single image i will show my code
public class FotosurpriseActivity extends Activity {
/** Called when the activity is first created. */
Bitmap overlay;
Paint pTouch;
int X = -100;
int Y = -100;
Canvas c2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.android);
Bitmap mBitmapover = BitmapFactory.decodeResource(getResources(), R.drawable.ss);
overlay = BitmapFactory.decodeResource(getResources(),R.drawable.ss).copy(Config.ARGB_8888, true);
c2 = new Canvas(overlay);
pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);
// pTouch.setXfermode(new PorterDuffXfermode(Mode.TARGET);
pTouch.setColor(Color.TRANSPARENT);
pTouch.setMaskFilter(new BlurMaskFilter(15, Blur.NORMAL));
setContentView(new BitMapView(this, mBitmap,mBitmapover));
}
class BitMapView extends View {
Bitmap mBitmap = null;
Bitmap mBitmapover = null;
public BitMapView(Context context, Bitmap bm, Bitmap bmover) {
super(context);
mBitmap = bm;
mBitmapover = bmover;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_MOVE: {
X = (int) ev.getX();
Y = (int) ev.getY();
invalidate();
break;
}
case MotionEvent.ACTION_UP:
break;
}
return true;
}
#Override
protected void onDraw(Canvas canvas) {
// called when view is drawn
Paint paint = new Paint();
paint.setFilterBitmap(true);
// The image will be scaled so it will fill the width, and the
// height will preserve the image’s aspect ration
/* double aspectRatio = ((double) mBitmap.getWidth()) / mBitmap.getHeight();
Rect dest = new Rect(0, 0, this.getWidth(),(int) (this.getHeight() / aspectRatio));
double aspectRatio2 = ((double) mBitmapover.getWidth()) / mBitmapover.getHeight();
Rect dest2 = new Rect(0, 0, this.getWidth(),(int) (this.getHeight() / aspectRatio2));
canvas.drawBitmap(mBitmap, null, dest, paint);
canvas.drawBitmap(mBitmapover, null, dest2, paint); */
//draw background
canvas.drawBitmap(mBitmap, 0, 0, null);
//copy the default overlay into temporary overlay and punch a hole in it
c2.drawBitmap(mBitmapover, 0, 0, null); //exclude this line to show all as you draw
c2.drawCircle(X, Y, 80, pTouch);
//draw the overlay over the background
canvas.drawBitmap(overlay, 0, 0, null);
}
}
}
how can i make this happen?
The onDraw function draws to the view. You don't actually need to do that at all. You can do this all in memory where the bitmaps reside. You draw the other bitmap on C2 as well. You don't have to draw anything to canvas in the onDraw() all that does is draw that to the screen.