-2

a list of images and stickers(webp format) must be shown on a recycleview.

to show sticker on imageView, this [repository] (https://github.com/EverythingMe/webp-android) is used. this repository was one of suggested solution on this post(WebP for Android)

sticker file is readed from external storage, convert to byte array, by using library of the repository, byte array convert to bitmap, and finally bitmap is shown on imageView. below code convert sticker file to bitmap

private void ShowStickerOnImageView(String stickerPath){
File file = new File(stickerPath);
int size = (int) file.length();
byte[] bytes = new byte[size];

BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
buf.read(bytes, 0, bytes.length);
buf.close();

Bitmap bitmap = null;
boolean NATIVE_WEB_P_SUPPORT = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2;
if (!NATIVE_WEB_P_SUPPORT) {
    bitmap = WebPDecoder.getInstance().decodeWebP(bytes);
} else {
    bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}

holder.imageView.setImageBitmap(bitmap);
}

.....

public Bitmap decodeWebP(byte[] encoded, int w, int h) {
int[] width = new int[]{w};
int[] height = new int[]{h};

byte[] decoded = decodeRGBAnative(encoded, encoded.length, width, height);
if (decoded.length == 0) return null;

int[] pixels = new int[decoded.length / 4];
ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);

return Bitmap.createBitmap(pixels, width[0], height[0], Bitmap.Config.ARGB_8888);
}

when 'NATIVE_WEB_P_SUPPORT' is false, 'decodeWebP' method is called, this method work fine in most of the time, but sometimes 'out of memory' error is happened on this method. most of the time, this error is happened on these lines

int[] pixels = new int[decoded.length / 4];
ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);
return Bitmap.createBitmap(pixels, width[0], height[0], Bitmap.Config.ARGB_8888);

i found that byte array length of sticker file is big , can i decrease sticker file size programmatically? i want to find solution, to decrease byte array size.

Community
  • 1
  • 1
Motahare Sehati
  • 149
  • 2
  • 9

1 Answers1

0

You are creating a Bitmap that is being used as native size, but applied to an ImageView. Decrease the Bitmap to the size of the View:

Bitmap yourThumbnail= Bitmap.createScaledBitmap(
   theOriginalBitmap,
   desiredWidth,
   desiredHeight,
   false
);

Do note that:

public static Bitmap createBitmap(int colors[], int width, int height, Config config) {
    return createBitmap(null, colors, 0, width, width, height, config);
}

Will call

public static Bitmap createBitmap(DisplayMetrics display, int colors[],
        int offset, int stride, int width, int height, Config config)

And that will lead to:

Bitmap bm = nativeCreate(colors, offset, stride, width, height,
                        config.nativeInt, false);

Basically, you cannot create a huge Bitmap in memory, for no reason. If this is for phones, assume a 20 MB size for application. An 800*600*4 image, yelds 1920000 bytes. Lower Image quality, such as using RGB_565 (half byte ammount per pixel, compared with RGB_8888), or pre-re-scale your source Bit map.

Bonatti
  • 2,778
  • 5
  • 23
  • 42
  • using RGB_565 cause image low quality especially if a text used in sticker – Motahare Sehati Dec 04 '16 at 18:31
  • Like on the answer, the main issue you have is creating a `Bitmap` bigger than your display. Either dont load it, alter the original bitmap or file, then load a scaled version, or get your `View` size, then load the `Bitmap` according to that size. There is no "pre Android 4.0" default library to use. And there are reasons for that, if you need to display a large `Bitmap`, on low resource devices, look for help on google, but dont expect a `Magically.load(largeBitmap)` function – Bonatti Dec 05 '16 at 10:59