Save bitmap from custom view that has animation going through onDraw method
So, I have an animation created with a bunch of bitmaps drawn in the onDraw () method of a custom view. There is a stream of updates that calls a method on the custom view that changes the positions of the bitmaps to be drawn with the onDraw () method. I would like to do this in order to keep the bitmap generated every time the update stream is finished so that I can create a gif from the bitmaps that I save.
I found the below code to save a png from a bitmap stored in memory on an SD card and that works with the saved bitmap, but I am having problems with getDrawingCache ():
public void saveView(){
if(counter < 200){
try {
counter++;
System.out.println("Counter : " + counter);
File file = new File(path, "star"+counter+".png");
file.delete();
OutputStream fOut = new FileOutputStream(file);
buildDrawingCache();
getDrawingCache().compress(Bitmap.CompressFormat.PNG, 100, fOut);
destroyDrawingCache();
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Doing this essentially does two things right now:
1) It takes about 50 images and saves them on the SD card. @ about 50, this forces the heap to get to the big one (I think destroyDrawingCache () can't actually finish because of this in a separate thread)
2) In the pictures taken, you can see the scan lines from the buffer update, because I am taking from the buffer that is being updated.
It would seem that getDrawingCache is calling onDraw (), so I cannot have this on the UI thread in onDraw itself.
If possible, please help.
source to share
You shouldn't call getDrawingCache()
from outside the UI. This is why the bitmaps you received have partially updated the scan lines. Call saveView()
directly from onDraw()
. Only file operations can be performed on separate threads after a clone of the cached bitmap is created.
Note. Can you call setDrawingCacheEnabled(true)
? so you don't need to call buildDrawingCache()
and destroyDrawingCache()
. Also, if your device is hardware accelerated, you need to make a call setLayerType(LAYER_TYPE_SOFTWARE, null)
.
Another solution is to get a bitmap by calling View.draw(android.graphics.Canvas)
on a new canvas containing an empty bitmap.
source to share