Why is drawing to the Android canvas not modifying my bitmap? - android

Looking for help troubleshooting why the bitmap is not being modified by this drawing. Have looked at numerous examples, and my code seems to match what is listed. What am I missing?
This is the relevant code (the class is constructed elsewhere, and the drawSomething() call is in an onTouchEvent handler). I've shortened the code for brevity:
class MyView extends View {
Bitmap mBitmap;
BitmapDrawable mBitmapDrawable;
Canvas mCanvas;
Paint mPaint;
public MyView(Context context) {
super(context);
mBitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
mBitmapDrawable = new BitmapDrawable(getResources(), mBitmap);
mCanvas = new Canvas(mBitmap);
mCanvas.setBitmap(mBitmap);
mPaint = new Paint();
mPaint.setColor(Color.parseColor("#00FF00"));
mPaint.setStrokeWidth(10);
}
public void drawSomething() {
mCanvas.drawColor(0xFF00FF00); // This should "fill" the canvas
int radius = 10;
mCanvas.drawCircle(50, 50, radius, mPaint); // This should draw a circle at (50, 50)
int count=0;
for (int i=0; i<mBitmap.getWidth(); i++)
{
for (int j=0; j<mBitmap.getHeight(); j++)
{
if (mBitmap.getPixel(i, j) > 0)
{
count += 1;
}
}
}
if (count == 0)
{
Log.v("MyApp", "Nothing was drawn!");
}
}
}

Figured out the problem. Turns out that the canvas drawing was working as expected (no surprise there). There were two other issues.
I overlooked the signed-ness of a Java int datatype. The int value 0xFF00FF00 evaluates less than 0. This explains why the count in my troubleshooting code evaluated to 0.
I was not seeing any drawing in the bitmap because I was ultimately using the draw method of the mBitmapDrawable object to draw the bitmap to the screen. After changing my code to use the drawBitmap method of the Canvas object, the mutable bitmap was properly drawn. I speculate that the BitmapDrawable makes a copy of the provided bitmap in its constructor, and therefore I was not seeing the modifications I had made to the bitmap.

Related

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.

Draw on canvas without making previously drawn bitmap cleared

I need to draw bitmap on canvas and then start drawing over it. When I draw other objects on canvas the previously drawn bitmap gets cleared. To avoid the bitmap from getting cleared, I have to draw it in each ondraw() call. There must be some other way to just update over the previously drawn drawing, else it would be really efficient as I may have to draw many bitmaps.
#Override
protected void onDraw(Canvas mCanvas) {
for (Pair<Path, Paint> p : paths) {
mCanvas.drawPath(p.first, p.second);
}
if(merge){
canvas.drawBitmap(bmp, transform, new Paint());
}
}
So, what would be the most efficient way to draw over previously drawn drawing without losing it.
I tried writing this by implementing the chess pieces using BitmapDrawable, and then only call invalidateDrawable on the piece that was moved.
That worked fine, but when I checked which parts are redrawn, it turned out that everything seems to be redrawn (or at least all the onDraw functions are being called).
Checking the documentation of the invalidate method on the View class again, I found the following:
This method was deprecated in API level 28.
The switch to hardware accelerated rendering in API 14 reduced the importance of the dirty rectangle. In API 21 the given rectangle is ignored entirely in favor of an internally-calculated area instead. Because of this, clients are encouraged to just call invalidate().
This suggests to me that maybe there is simply no need to worry about this case. It seems that Android internally figures out what to redraw, and efficiently does so.
Just in case it may help, you can find the working version on my GitHub.
Additionally, here is the most relevant part of the App:
public class RedrawTest extends View {
private class ChessPiece extends BitmapDrawable {
final int id;
public ChessPiece(Context context, int _id) {
super(getResources(), getBitmapFromAsset(context, "chess_piece.png"));
id = _id;
}
}
final Bitmap chessboard;
final ChessPiece[] chessPieces;
final Rect boardSize;
final Paint paint = new Paint();
final ViewOverlay overlay;
final int borderSize = 32;
final int nChestPieces = 6;
private static Bitmap getBitmapFromAsset(Context context, String filePath) {
AssetManager assetManager = context.getAssets();
InputStream inputStream;
Bitmap bitmap = null;
try {
inputStream = assetManager.open(filePath);
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (IOException e) {
// handle exception
}
return bitmap;
}
public RedrawTest(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
chessboard = getBitmapFromAsset(context, "chessboard.jpg");
boardSize = new Rect(
borderSize, borderSize,
chessboard.getWidth()-borderSize, chessboard.getHeight()-borderSize
);
overlay = getOverlay();
chessPieces = new ChessPiece[nChestPieces];
for (int i=0; i<nChestPieces; ++i) {
chessPieces[i] = new ChessPiece(context, i);
chessPieces[i].setBounds(getBoardRect(0, i));
overlay.add(chessPieces[i]);
}
}
public void redraw(int i, int j, int pieceId) {
chessPieces[pieceId].setBounds(getBoardRect(i, j));
invalidateDrawable(chessPieces[pieceId]);
}
private Rect getBoardRect(int i, int j) {
return new Rect(
boardSize.left + j*boardSize.width()/8 + 5,
boardSize.top + i*boardSize.height()/8 + 5,
boardSize.left + (j+1)*boardSize.width()/8 - 5,
boardSize.top + (i+1)*boardSize.height()/8 - 5);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(this.chessboard, 0, 0, paint);
}
}
I found that not using a custom view class and the onDraw method makes it so the canvas doesn't clear and hence I had to manually clear it myself for my purposes.
See below for the code, just remove the canvas.drawColor line as that is where I paint the canvas clear again.
public void doCanvas(){
//Create our resources
Bitmap bitmap = Bitmap.createBitmap(mLittleChef.getWidth(), mLittleChef.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
final Bitmap chefBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.dish_special);
final Bitmap starBitmap= BitmapFactory.decodeResource(getResources(),R.drawable.star);
//Link the canvas to our ImageView
mLittleChef.setImageBitmap(bitmap);
ValueAnimator animation= ValueAnimator.ofInt(canvas.getWidth(),0,canvas.getWidth());
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (Integer) animation.getAnimatedValue();
//Clear the canvas
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.drawBitmap(chefBitmap, 0, 0, null);
canvas.save();
canvas.translate(value,0);
canvas.drawBitmap(starBitmap, 0, 0, null);
canvas.restore();
//Need to manually call invalidate to redraw the view
mLittleChef.invalidate();
}
});
animation.addListener(new AnimatorListenerAdapter(){
#Override
public void onAnimationEnd(Animator animation) {
simpleLock= false;
}
});
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(mShortAnimationDuration);
animation.start();
}
In pixi.js there is options.clearBeforeRender (https://pixijs.download/dev/docs/PIXI.CanvasRenderer.html) and pixi.js probably using https://www.w3schools.com/tags/canvas_clearrect.asp .
Your question already been asked (but 7y ago, so maybe outdated), and they did as you do How to save objects previously drawn to the Canvas on a redraw? .
You may want to profile, to make sure it is a performance issue, maybe the way you do it doesn't look efficient, but is efficient, if you see what I mean.

Java: Android: changing color of bitmap on canvas in code

I'm trying to do something that I thought was simple but apparently it's not!
I'm making a simple app to learn Android game dev. At the moment, the user clicks on the screen and a sprite is displayed. The sprite is just a solid white square. I want to change that in the code.
I think I'm spoiled by C#/XNA where, if a sprite is solid white, you can set the colour in the draw method. That doesn't seem to work here, even when I used the paint function. I've done a bit of research but all the solutions don't seem to be quite what I'm looking for, and also very complicated. I'm hoping to find something at least simpler to mess with if I can't find the exact solution. Here's the relevant code so far:
From the view:
private Sprite createSprite(int resouce) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
return new Sprite(this, bmp, touchX, touchY);
the view onDraw method:
if (touched == true)
{
canvas.drawColor(colors[nextColor]);
lastColor = colors[nextColor];
//add bitmap to array
sprites.add(createSprite(R.drawable.test));
//draw sprites
for (Sprite sprite : sprites) {
sprite.onDraw(canvas);
}
relevant code from the sprite class:
private Paint paint = new Paint();
public Sprite(DaphnyView daphView, Bitmap bmp, int positionX, int positionY) {
width = bmp.getWidth();
height = bmp.getHeight();
DaphView = daphView;
Bmp = bmp;
PositionX = positionX;
PositionY= positionY;
paint.setColor(Color.GREEN);
}
public void onDraw(Canvas canvas) {
canvas.drawBitmap(Bmp, PositionX, PositionY, paint);
}
If anyone can help me out or at least point me to a good starting point, it would be a great help. Thanks!
I found a solution by creating a new canvas to modify the bitmap, then passing this modified bitmap back to the original canvas.

Draw multiple times from a single bitmap on a canvas

Basically I have the following bitmap:
Bitmap cloud;
cloud = BitmapFactory.decodeResource(getResources(), R.drawable.cloud);
What I want to do is draw the same bitmap(in this case cloud) multiple times in different(random) locations on canvas. I want to do this in the OnDraw method of my view.
So the final product should look like this:
However
This is the code for drawing the bitmap multiple times on the same canvas:
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
// canvas.drawColor(Color.BLUE);
//drawBackground(canvas);
//objectMovement(canvas);
for (int i = 0; i < 500; i += 50) {
canvas.drawBitmap(cloud, 50 + rand.nextInt(350),
10 + rand.nextInt(350), null);
}
invalidate();
}
As you can see, I'm using random to generate the position of the bitmap, and every time the bitmap is drawn in a different place on the canvas.
The only problem is, every time invalidate() is being called, the drawing in the for loop happens again. Because of this, it looks like the drawings(cloud) is moving very fast all over the place.
After searching for a while, I found this question:
Draw multiple times from a single bitmap
It's pretty much the same question as my question, but unfortunately, there is no right answer there.
So how do I achieve this?
Thanks!
The first problem is that you are reading in the bitmap 10 times per frame which is completely unnecessary. You should read the bitmap in once when you instantiate your class. I've also added a Paint. I don't know if it's completely necessary but just incase you decide to do more in your draw method it's there.
public class MyView extends View
{
private Bitmap _cloud;
private Paint _paint;
public MyView(Context context)
{
super(context);
_cloud = BitmapFactory.decodeResource(getResources(),R.drawable.cloud);
_paint = new Paint();
}
protected void onDraw(Canvas canvas)
{
for(int i = 0; i < 500; i += 50)
{
canvas.drawBitmap(_cloud, 50 + rand.nextInt(350rand.nextInt(350)), 10 + i, _paint);
}
}
}

Android, canvas: How do I clear (delete contents of) a canvas (= bitmaps), living in a surfaceView?

In order to make a simple game, I used a template that draws a canvas with bitmaps like this:
private void doDraw(Canvas canvas) {
for (int i=0;i<8;i++)
for (int j=0;j<9;j++)
for (int k=0;k<7;k++) {
canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } }
(The canvas is defined in "run()" / the SurfaceView lives in a GameThread.)
My first question is how do I clear (or redraw) the whole canvas for a new layout?
Second, how can I update just a part of the screen?
// This is the routine that calls "doDraw":
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
if (mMode == STATE_RUNNING)
updateGame();
doDraw(c); }
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c); } } } }
Draw transparent color with PorterDuff clear mode does the trick for what I wanted.
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
How do I clear (or redraw) the WHOLE canvas for a new layout (= try at the game) ?
Just call Canvas.drawColor(Color.BLACK), or whatever color you want to clear your Canvas with.
And: how can I update just a part of the screen ?
There is no such method that just update a "part of the screen" since Android OS is redrawing every pixel when updating the screen. But, when you're not clearing old drawings on your Canvas, the old drawings are still on the surface and that is probably one way to "update just a part" of the screen.
So, if you want to "update a part of the screen", just avoid calling Canvas.drawColor() method.
Found this in google groups and this worked for me..
Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, clearPaint);
This removes drawings rectangles etc. while keeping set bitmap..
use the reset method of Path class
Path.reset();
I tried the answer of #mobistry:
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
But it doesn't worked for me.
The solution, for me, was:
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
Maybe some one has the same problem.
mBitmap.eraseColor(Color.TRANSPARENT);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
please paste below code on surfaceview extend class constructor.............
constructor coding
SurfaceHolder holder = getHolder();
holder.addCallback(this);
SurfaceView sur = (SurfaceView)findViewById(R.id.surfaceview);
sur.setZOrderOnTop(true); // necessary
holder = sur.getHolder();
holder.setFormat(PixelFormat.TRANSPARENT);
xml coding
<com.welcome.panelview.PanelViewWelcomeScreen
android:id="#+id/one"
android:layout_width="600px"
android:layout_height="312px"
android:layout_gravity="center"
android:layout_marginTop="10px"
android:background="#drawable/welcome" />
try above code...
Here is the code of a minimal example showing that you always have to redraw every pixel of the Canvas at each frame.
This activity draw a new Bitmap every second on the SurfaceView, without clearing the screen before.
If you test it, you will see that the bitmap is not always written to the same buffer, and the screen will alternate between the two buffers.
I tested it on my phone (Nexus S, Android 2.3.3), and on the emulator (Android 2.2).
public class TestCanvas extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new TestView(this));
}
}
class TestView extends SurfaceView implements SurfaceHolder.Callback {
private TestThread mThread;
private int mWidth;
private int mHeight;
private Bitmap mBitmap;
private SurfaceHolder mSurfaceHolder;
public TestView(Context context) {
super(context);
mThread = new TestThread();
mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mWidth = width;
mHeight = height;
mThread.start();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {/* Do nothing */}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mThread != null && mThread.isAlive())
mThread.interrupt();
}
class TestThread extends Thread {
#Override
public void run() {
while (!isInterrupted()) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
synchronized (mSurfaceHolder) {
c.drawBitmap(mBitmap, (int) (Math.random() * mWidth), (int) (Math.random() * mHeight), null);
}
} finally {
if (c != null)
mSurfaceHolder.unlockCanvasAndPost(c);
}
try {
sleep(1000);
} catch (InterruptedException e) {
interrupt();
}
}
}
}
}
For me calling Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) or something similar would only work after I touch the screen. SO I would call the above line of code but the screen would only clear after I then touched the screen. So what worked for me was to call invalidate() followed by init() which is called at the time of creation to initialize the view.
private void init() {
setFocusable(true);
setFocusableInTouchMode(true);
setOnTouchListener(this);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(6);
mCanvas = new Canvas();
mPaths = new LinkedList<>();
addNewPath();
}
Erasing on Canvas in java android is similar erasing HTML Canvas via javascript with globalCompositeOperation. The logic was similar.
U will choose DST_OUT (Destination Out) logic.
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
Note: DST_OUT is more useful because it can erase 50% if the paint color have 50% alpha. So, to clear completely to transparent, the alpha of color must be 100%. Apply paint.setColor(Color.WHITE) is recommended. And make sure that the canvas image format was RGBA_8888.
After erased, go back to normal drawing with SRC_OVER (Source Over).
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
Update small area display literally will need to access graphic hardware, and it maybe not supported.
The most close for highest performance is using multi image layer.
With the following approach, you can clear the whole canvas or just a part of it.
Please do not forget to disable Hardware acceleration since PorterDuff.Mode.CLEAR doesn’t work with hardware acceleration and finally call setWillNotDraw(false) because we override the onDraw method.
//view's constructor
setWillNotDraw(false);
setLayerType(LAYER_TYPE_SOFTWARE, null);
//view's onDraw
Paint TransparentPaint = new Paint();
TransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRect(0, 0, width, height, TransparentPaint);
Don't forget to call invalidate();
canvas.drawColor(backgroundColor);
invalidate();
path.reset();
I found my solution.
PaintView class:
public void clear() {
mPath.reset();
mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
paths.clear();
}
And MainActivity:
clear_canvas_.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
paintView.clear();
}
});
Your first requirement, how to clear or redraw whole canvas - Answer - use canvas.drawColor(color.Black) method for clearing the screen with a color of black or whatever you specify .
Your second requirement, how to update part of the screen - Answer - for example if you want to keep all other things unchanged on the screen but in a small area of screen to show an integer(say counter) which increases after every five seconds. then use canvas.drawrect method to draw that small area by specifying left top right bottom and paint. then compute your counter value(using postdalayed for 5 seconds etc., llike Handler.postDelayed(Runnable_Object, 5000);) , convert it to text string, compute the x and y coordinate in this small rect and use text view to display the changing counter value.
Try to remove the view at onPause() of an activity and add onRestart()
LayoutYouAddedYourView.addView(YourCustomView);
LayoutYouAddedYourView.removeView(YourCustomView);
The moment you add your view, onDraw() method would get called.
YourCustomView, is a class which extends the View class.
In my case, I draw my canvas into linearlayout.
To clean and redraw again:
LinearLayout linearLayout = findViewById(R.id.myCanvas);
linearLayout.removeAllViews();
and then, I call the class with the new values:
Lienzo fondo = new Lienzo(this,items);
linearLayout.addView(fondo);
This is the class Lienzo:
class Lienzo extends View {
Paint paint;
RectF contenedor;
Path path;
ArrayList<Items>elementos;
public Lienzo(Context context,ArrayList<Items> elementos) {
super(context);
this.elementos=elementos;
init();
}
private void init() {
path=new Path();
paint = new Paint();
contenedor = new RectF();
paint.setStyle(Paint.Style.FILL);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
contenedor.left = oneValue;
contenedor.top = anotherValue;
contenedor.right = anotherValue;
contenedor.bottom = anotherValue;
float angulo = -90; //starts drawing at 12 o'clock
//total= sum of all element values
for (int i=0;i<elementos.size();i++){
if (elementos.get(i).angulo!=0 && elementos.get(i).visible){
paint.setColor(elementos.get(i).backColor);
canvas.drawArc(contenedor,angulo,(float)(elementos.get(i).value*360)/total,true,paint);
angulo+=(float)(elementos.get(i).value*360)/total;
}
} //for example
}
}
In my case, creating canvas every time worked for me, even though it's not memory-friendly
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageBitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), bm.getConfig());
canvas = new Canvas(imageBitmap);
canvas.drawBitmap(bm, 0, 0, null);
I had to use a separate drawing pass to clear the canvas (lock, draw and unlock):
Canvas canvas = null;
try {
canvas = holder.lockCanvas();
if (canvas == null) {
// exit drawing thread
break;
}
canvas.drawColor(colorToClearFromCanvas, PorterDuff.Mode.CLEAR);
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
The following worked for me:
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SCREEN);
Just call
canvas.drawColor(Color.TRANSPARENT)

Categories

Resources