Problem on some phones when encoding a bitmap to a byte[] array
I have an icon that is loaded from the app manager. It is normally small, usually 48x48. I save this icon and load it back later on.
Some users are reporting problems when I try to load the saved icon. This occurs for different icons for different users and the only common denominator is that they all have phones running Android 1.5开发者_如何学Python (Sprint Hero, Sprint Moment, Droid Eris).
//Returns a valid drawable 100% of the time
Drawable drawable = activityInfo.loadIcon(manager);
//Creates a bitmap 100% of the time
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
//This drawable can always be displayed (so you know the bitmap is good here.
Drawable testDrawable = new BitmapDrawable(bitmap);
//There are no errors thrown from these lines but in ALL cases if it fails the length of the byte[] array b is 48.
//When it succeeds the length is much bigger 1000+.
ByteArrayOutputStream out= new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, out);
byte[] b = out.toByteArray();
I can easily tell that the users icon failed to load because you cannot create a valid bitmap back from the 48 length byte array.
What can I change in the 3 lines that create my byte array to fix the problem? I have also tried, with nochange:
bitmap.compress(CompressFormat.PNG, 100, out);
I experienced similar problem on Android 1.5, while Android 1.6, 2.1 and 2.2 worked fine.
In my case bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputstream) failed only on bitmaps created from PNG images using BitmapFactory.decodeByteArray(...)
The workaround/solution for this problem was to clone such bitmap before calling its compress(...) method like in the code below
boolean success = bitmap.compress(CompressFormat.PNG, 100, outputStream);
if (! success) {
Bitmap cloneImg = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false);
outputStream = new ByteArrayOutputStream();
cloneImg.compress(CompressFormat.PNG, 100, outputStream);
}
You can also test the boolean returned by compress() to tell if the compression succeeded or not.
As for getting it to succeed, I don't know if there is enough information here to do that. Specifically I am curious as to the true location of the OutputStream as I assume the byteArrayOutputStream is not the actual stream used to save the icon for later use. Since they are on 1.5 devices, I have a hunch that you are trying to store this icon to either your cache dir or a directory located on phone storage. I mean it could range from a faulty I/O device to insufficient storage space. My hunch from it happening on 1.5 devices is that there is not enough space on the physical device as most (not all) phones on 1.5 do not ship with much internal storage.
Also I don't think changing the compression quality on PNG format will matter as PNG is lossless.
精彩评论