webview.capturePicture() to create a Picture object that contains all the drawing objects for a webpage.
I can successfully render this Picture object to a bitmap using the
canvas.drawPicture(picture, dst) with no problems. However when I use
picture.writeToStream(fos) to serialize the picture object out to file, and then
Picture.createFromStream(fis) to read the data back in and create a new picture object, the resultant bitmap when rendered as above is missing any larger images (anything over around 20KB! by observation).
This occurs on all the Android OS platforms that I have tested 1.5, 1.6 and 2.1. Looking at the native code for
Skia which is the underlying Android graphics library and the output file produced from the
picture.writeToStream() I can see how the file format is constructed. I can see that some of the images in this Skia spool file are not being written out (the larger ones), the code that appears to be the problem is in
skBitmap.cpp in the method
void SkBitmap::flatten(SkFlattenableWriteBuffer& buffer) const;
It writes out the bitmap
fWidth, fHeight, fRowBytes, FConfig and isOpaque values but then just writes out
SERIALIZE_PIXELTYPE_NONE (0). This means that the spool file does not contain any pixel information about the actual image and therefore cannot restore the picture object correctly.
Effectively this renders the
writeToStream and createFromStream() APIs useless as they do not reliably store and recreate the picture data.
Has anybody else seen this behaviour and if so am I using the API incorrectly, can it be worked around, is there an explanation i.e. incomplete API / bug and if so are there any plans for a fix in a future release of Android?
Thanks in advance.
That's the way the API is meant to work. It was never intended for long term storage, but to store flattened in the current process, or to send to another process. What you are asking for will not be supported.
On the Honeycomb platform it appears that writeToStream() and createFromStream() now store and recreate the Picture object including large image data.
However it does come with the following caveats:
- The image data used in a picture must be of an immutable type.
- The image data must have been created with the following BitmapFactory.Options set to true, inInputShareable and inPurgeable. This can be done by using BitmapFactory.decodeResource() passing in the BitmapFactory.Options.
It so happens that Pictures created by WebView 'do' contain suitable images that meet this criteria and therefore can be serialized and restored.
I have not confirmed as yet that Ice Cream Sandwich also works but I am assuming/hoping that it will.