Reputation: 1362
So I have an animation that is being created by having a bunch of bitmaps drawn in the onDraw() method of a custom view. There is an update thread that calls a method in the custom view that changes the positions of the bitmaps to be drawn by the onDraw() method. What I would like to do is to save the bitmap created each time the update thread 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 to the SD card and that works with a stored bitmap but I'm having trouble 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 to the sd card. @ around 50 it causes the heap to get to large (i guess destroyDrawingCache() is unable to actually finish due to this is in a seperate thread)
2) In the pictures taken, you can see the scan lines from the buffer updating because I'm taking from a buffer that gets updated.
It would seem the getDrawingCache calls onDraw() as well which is why I can't have this on the UI thread in the onDraw itself.
If this is possible please help.
Upvotes: 4
Views: 1461
Reputation: 28767
You should not call getDrawingCache()
from outside the UI thread. That's why the bitmaps you get have partially updated scan lines. Call saveView()
directly from onDraw()
. Only the file operations may be run on separate threads after making a clone of the cached bitmap.
Note: You can call setDrawingCacheEnabled(true)
? so that you don't have to call buildDrawingCache()
and destroyDrawingCache()
. Also if your device has hardware acceleration is turned on, you'll have to call setLayerType(LAYER_TYPE_SOFTWARE, null)
.
Another solution is to get the bitmap by calling View.draw(android.graphics.Canvas)
on a new canvas that holds a blank bitmap.
Upvotes: 2