How to know that Canvas has used bitmap object - android

Hi I am creating Bitmap object and using in canvas, like below code
Bitmap result = Bitmap.createBitmap(loadedImage.getWidth(), loadedImage.getHeight(), Config.ARGB_8888);
Canvas mCanvas = new Canvas(result);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
mCanvas.drawBitmap(blurBitmap, 0, 0, null);
mCanvas.drawBitmap(loadedImage, 0, 0, paint);
paint.setXfermode(null);
ivBlur.setImageBitmap(result);
// now i don't want Bitmap "result" so I am recycling it
if (result != null && !result.isRecycled())
result.recycle();
}
But from above code I am getting an error like
trying to use recycled bitmap android
How to fix "canvas: trying to use a recycled bitmap error"?
trying to use a recycled bitmap android.graphics.Bitmap
Canvas: trying to use a recycled bitmap android.graphics.Bitmap in android
If I don't write last three lines it is working perfect,
It may be because Canvas is using Bitmap "result" object and I am recycling "result"
Because of this bitmap is taking huge space, I have to recycle this bitmap otherwise I will get
java.lang.OutofMemoryError: bitmap size exceeds VM budget.
So does anyone know how can I get that, "Canvas has used bitmap object and now I can recycle result object".

The issue isn't the the Canvas has used the bitmap. The issue is that you passed the Bitmap to an ImageView that needs it to draw itself Once you pass that Bitmap to an ImageView, you can't recycle it for as long as the ImageView is alive.
You can recycle the bitmap only after the ImageView with the Bitmap is removed from the view hierarchy and never used again. In that case, it's easier to just let the garbage collector handle it.
If you instead need a smaller Bitmap, you should create and draw into that smaller Bitmap before sending it to the ImageView.

Related

Android: Efficiently draw on images

The helper function below draws a rectangle on top of input bitmap and returns a thumbnail bitmap. However, I run into java OutOfMemory Error when I call this helper around 1000 times from an activity to populate a list of thumbnails. I tried resizing the tempScaledBitmap to 375, 500 but the quality of the thumbnail image is poor.
Also, I was unable to directly draw on inputBitmap as it was immutable.
What is an efficient way to display a list of 1000 plus thumbnails in an activity?
private static Bitmap drawOnCanvas(Bitmap inputBitmap, FramePoint[] points, ColorCode colorCode){
Bitmap tempScaledBitmap = Bitmap.createScaledBitmap(inputBitmap, 750, 1000, false);
//draw path
Canvas canvas = new Canvas(tempScaledBitmap);
// Path
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(colorCode.equals(ColorCode.GREEN)?Color.GREEN:(colorCode.equals(ColorCode.RED)?Color.RED:Color.BLUE));
paint.setStrokeWidth(5);
Path p = new Path();
p.moveTo(points[0].getPointX(), points[0].getPointY());
p.lineTo(points[1].getPointX(), points[1].getPointY());
p.lineTo(points[2].getPointX(), points[2].getPointY());
p.lineTo(points[3].getPointX(), points[3].getPointY());
p.close();
canvas.drawPath(p, paint);
return tempScaledBitmap;
}
After each call to drawOnCanvas you should recycle your bitmaps:
inputBitmap.recycle();
Also recycle the tempScaledBitmap after they are assigned to ImageViews or wherever to prevent this OOM errors.
Also, you could consider using picasso or glide. For me, it's the best option of all.

Clear Bitmap in Android

I create first chart using bitmap and canvas. How I can clear bitmap for drawing new chart?
ImageView imageView = new ImageView(this);
Bitmap bitmap = Bitmap.CreateBitmap(w, h, Bitmap.Config.Argb8888);
Canvas canvas = new Canvas(bitmap);
...
imageView.SetImageBitmap(bitmap);
relativeLayout.AddView(imageView);
You can use eraseColor on bitmap to set its color to Transparent. It will useable again without recreating it.
bitmap.eraseColor(Color.TRANSPARENT);
Further reading here
ImageView imageView = new ImageView(this);
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// Your Other code
imageView.setImageBitmap(bitmap);
relativeLayout.AddView(imageView);
Now release memory of bitmap by below code
bitmap.recycle();
Help of recycle() method of bitmap as per this.
public void recycle ()
Added in API level 1
Free the native object associated with this bitmap, and clear the reference to the pixel data. This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references. The bitmap is marked as "dead", meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing. This operation cannot be reversed, so it should only be called if you are sure there are no further uses for the bitmap. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.
The solution was to use
bitmap.eraseColor

android save text drawed bitmap to jpeg file

I try to make an android app
and it must contain bitmap to jpeg file method
Here is what i have to do
1.create BitmapDrawable object
BitmapDrawable bitmapDrawable = (BitmapDrawable)res.getDrawable(R.drawable.my_pic);
2.create Bitmap object
Bitmap bit = bitmapDrawable.getBitmap();
3.create set Bitmap on canvas object
canvas.drawBitmap(bit,0,0,null)
4.drawText "helloworld" on canvas
Paint pnt = new Paint();
pnt.setColor(Color.BLACK);
canvas.drawText("helloworld",100,100,pnt);
canvas.save();
canvas.restore();
and this code is what I tried to do to save Bitmap(or canvas) to Jepg File
a.
bit.compress(Bitmap.CompressFormat.JEPG, 100 , fileOutputStream);
but this can save original image(without text)
so, I used code b.
b.
view.setDrawingCacheEnabled(true);
Drawable drawable =getResources().getDrawable(R.drawable.my_pic);
view.layout(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
view.bulidDrawingCache(true);
Bitmap save_bit = view.getDrawingCache();
save_bit.compress(Bitmap.CompressFormat.JPEG, 100, fos);
and this cause nullpoint exception, and logcat send me a message 'View too large to fit into drawing cache, needs 31325840 bytes, only 3686400 available'
what do I do to save text drawed bitmap to file
please give me your opinion

Cannot draw on bitmap loaded canvas

I am trying to create an image save and retrieve feature in android. The code I have for creating a jpg file from canvas is as below
Bitmap bitmap = Bitmap.createBitmap( view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
I am trying to read the jpg file and create image on canvas using
Bitmap bMap = BitmapFactory.decodeStream(buf);
Bitmap workingBitmap = Bitmap.createBitmap(bMap);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
view.mybitmap = mutableBitmap;
view.onDraw(view.Canvas);
The code I have in onDraw is
canvas.drawBitmap(view.mybitmap, 0, 0, view.myPaint);
This draws the bitmap on canvas correctly from the stored jpg file but I am not able to draw anything on the canvas after that. Has it loaded a immutable bitmap image on canvas which I am not able to edit?
Any help will be appreciated! Thanks!
You shouldn't need to be calling the ondraw method directly like you are doing currently. For a custom view class all you should need to be calling is view.invalidate(); This will auto call the ondraw method and re-draw the canvas. You will probably need to update the logic in your ondraw method to handle the cases where you want to draw additional things on the canvas.

Modifying Bitmap from resources

I'm trying to draw some addition to my ImageView's content, which is represented by Drawable from resources. I know that all Drawables from resources are immutable by default, but even after I call mutable() method and get Bitmap from this Drawable to pass it to Canvas object I get java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor. Here is the code:
Drawable homeImage = mHomeImage.getBackground(); // my ImageView
homeImage.mutate();
Canvas c = new Canvas(((BitmapDrawable)homeImage).getBitmap());
Is there any way to modify this Bitmap without creating it's copy?
Try this
Bitmap bmp1 = (((BitmapDrawable)homeImage).getBitmap())
.copy(Config.ARGB_8888, true);
Canvas c = new Canvas(bmp1);
You will need to create a new bitmap for the canvas. As the canvas uses the bitmap we pass to store whats drawn, the bitmap should be mutable.

Categories

Resources