“This is the 14th day of my participation in the First Challenge 2022.


Sometimes you see people using bitmaps with arguments like ARGB_8888/RGB_565. What are those arguments? What is the impact on Bitmap?


They are the four enumerated types of bitmap. Config. ARGB is alpha transparency and Red, Green and Blue, respectively

  • ARGB_8888: Use 8 bits to record 4 values, so each pixel takes up 32 bits.
  • ARGB_4444: Four bits are used to record four values, so each pixel takes up 16 bits.
  • RGB_565: Use 5, 6 and 5 bits to record RGB tricolor values, so each pixel will occupy 16 bits.
  • ALPHA_8: According to the comment, it should save no color value, only transparency (8 bits), each pixel will occupy 8 bits.

Memory size

So what happens to Bitmaps?

All comparisons are based on ARGB_8888.

  • ARGB_4444: Memory footprint reduced by half, but images per value are so distorted that this parameter itself is no longer recommended.
  • RGB_565: Memory usage reduced by half, transparency abandoned, tricolor value also partially lost, but image distortion is very small.
  • ALPHA_8: Memory footprint reduced by 3/4, no color, only transparency, i.e. black and white.
The test code
try {
    URL url = new URL("http://h.hiphotos.baidu.com/image/pic/item/b21c8701a18b87d6b025e513040828381f30fd53.jpg");
    HttpURLConnection connection = (HttpURLConnection)url.openConnection();
    InputStream in = connection.getInputStream();
    ByteArrayOutputStream content = new ByteArrayOutputStream();
    byte[] buffer = new byte[10 * 1024];
    int count;
    while((count = in.read(buffer)) > 0){
        content.write(buffer, 0, count);
    byte[] data = content.toByteArray();

    BitmapFactory.Options options1 = new BitmapFactory.Options();
    options1.inPreferredConfig = Bitmap.Config.ARGB_8888;
    Bitmap bitmap1 = BitmapFactory.decodeByteArray(data, 0 , data.length, options1);
    //System.out.println("bitmap ARGB_8888 length " + bitmap1.getByteCount());
    System.out.println("bitmap ARGB_8888 length " + bitmap1.getRowBytes() * bitmap1.getHeight());

    BitmapFactory.Options options2 = new BitmapFactory.Options();
    options2.inPreferredConfig = Bitmap.Config.RGB_565;
    Bitmap bitmap2 = BitmapFactory.decodeByteArray(data, 0 , data.length, options2);
    //System.out.println("bitmap RGB_565 length " + bitmap2.getByteCount());
    System.out.println("bitmap RGB_565 length " + bitmap2.getRowBytes() * bitmap2.getHeight());

    BitmapFactory.Options options3 = new BitmapFactory.Options();
    options3.inPreferredConfig = Bitmap.Config.ALPHA_8;
    Bitmap bitmap3 = BitmapFactory.decodeByteArray(data, 0 , data.length, options3);
    //System.out.println("bitmap ALPHA_8 length " + bitmap3.getByteCount());
    System.out.println("bitmap ALPHA_8 length " + bitmap3.getRowBytes() * bitmap3.getHeight());

    BitmapFactory.Options options4 = new BitmapFactory.Options();
    options4.inPreferredConfig = Bitmap.Config.ARGB_4444;
    Bitmap bitmap4 = BitmapFactory.decodeByteArray(data, 0 , data.length, options4);
    //System.out.println("bitmap ARGB_4444 length " + bitmap4.getByteCount());
    System.out.println("bitmap ARGB_4444 length " + bitmap4.getRowBytes() * bitmap4.getHeight());

} catch (Exception e) {
Copy the code

But the actual test found that the size of memory is not as expected, so why?


First, find no memory changes with ARGB_4444, see the official explanation

/** Each pixel is stored on 2 bytes. The three RGB color channels and the alpha channel (translucency) are stored with a  4 bits precision (16 possible values.) This configuration is mostly useful if the application needs to store translucency information but also needs to save memory. It is recommended to use ARGB_8888 instead of this configuration. Note: as of Build.VERSION_CODES.KITKAT, any bitmap created with this configuration will be created using ARGB_8888 instead. Deprecated Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead. **/
ARGB_4444   (4),
Copy the code

It turns out that after KITKAT (Android 19), this parameter is completely invalid and is replaced by ARGB_8888 by default, so the memory size does not change.


When testing, ALPHA_8 is also invalid. Not only is the memory size unchanged, but the image is still the original image without losing color.

Let’s look at the official comment on inPreferredConfig:

/* If this is non-null, the decoder will try to decode into this internal configuration. If it is null, or the request cannot be met, the decoder will try to pick the best matching config based on the system's screen depth, and characteristics of the original image such as if it has per-pixel alpha (requiring a config that also does). Image are loaded with the Bitmap.Config.ARGB_8888 config by default. */
public Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;
Copy the code

If the inPreferredConfig parameter is not null, the decoder will try to use the color mode specified by this parameter to decode the image. If this mode is not found, the decoder will automatically select the appropriate color mode to decode the image based on the characteristics of the original image and the screen depth of the current device.

InPreferredConfig is only a suggested option, and the final mode may not be specified, depending on the original image characteristics and the screen depth of the current device.

This is why we use ALPHA_8 wireless. In addition, RGB_565 may not work as described above, such as changing the image to the one below



Since ARGB_4444 has been abolished and ALPHA_8 needs to be used under special conditions, generally used for special requirements, most of us still use ARGB_8888 and RGB_565.

RGB_565 is a solution to the OOM by reducing memory overhead while maintaining image quality. However, it is important to note that RGB_565 has no transparency. If the image itself needs to be transparent, RGB_565 should not be used.

Also note that the mode set by inPreferredConfig does not necessarily take effect.

Pay attention to the public number: BennuCTech, get more dry goods!