Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Color formats (RGB565, ARGB8888)

    getHolder().setFormat(PixelFormat.RGBA_888);        

    Options options = new BitmapFactory.Options();       
    options.inDither=true;                               
    options.inScaled = true; 
    options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
    options.inPurgeable=true;

(Bitmat created using options above)

When using the above code, I get the following results.........

  • No colour banding on my Tablet device
  • Noticeable colour banding on test mobile (Samsung Galaxy Ace)

    getHolder().setFormat(PixelFormat.RGBA_888);        
    
    Options options = new BitmapFactory.Options();       
    options.inDither=true;                               
    options.inScaled = true; 
    options.inPreferredConfig = Bitmap.Config.ARGB_565; 
    options.inPurgeable=true;
    
  • No colour banding on my tablet

  • Noticible colour banding on the Galaxy Ace
  • Same results as above

    getHolder().setFormat(PixelFormat.RGB_565);     
    
    Options options = new BitmapFactory.Options();       
    options.inDither=true;                               
    options.inScaled = true; 
    options.inPreferredConfig = Bitmap.Config.RGB_565; 
    options.inPurgeable=true;
    
  • Colour banding on my tablet

  • colour banding on the SG Ace

    getHolder().setFormat(PixelFormat.RGB_565);     
    
    Options options = new BitmapFactory.Options();       
    options.inDither=true;                               
    options.inScaled = true; 
    options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
    options.inPurgeable=true;
    
  • Colour banding on my tablet

  • colour banding on the SG Ace

So, in conclusion, only the PixelFormat.xxxx part seems to make any difference. My understanding is that this is to set the holder colour format. This will affect everything drawn. (ie, everything will take that format).

Could someone explain what the purpose of the following line is please?

options.inPreferredConfig = Bitmap.Config.xxxxxxx

This doesn't seem to have any effect on the bitmap that has been drawn.

Performance is paramount, so I may have to change my original png files so they don't have gradients, (ie, to draw them as RGB565 - is this advisable or should I stick with 8888?) or should dithering sort that out? (because as you can see, I have it enabled but it doesn't seem to help).

Any ideas why the banding is always there on the Ace? Could it be a hardware limitation?

Thanks all this is very confusing.

(PS I have read the official guide, I always look at that before posting a question to SO as well as looking at other related SO questions, but the official guide (as is too often the case), doesn't clear this up for me and I couldn't find the answers through other questions, so apologies if it is here already).

like image 355
Zippy Avatar asked Mar 02 '13 18:03

Zippy


2 Answers

565 format is default since it can be drawn quicker and requires less processing power. As for your SG Ace, I believe that a while back only certain versions of Android supported the 8888 color.

To get one of my app backgrounds to not band, I had to do the following:

1 - Add background to drawable folder

2 - Create background_dithered.xml with the following content:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="true"
    android:src="@drawable/background" />

3 - in Activity code:

@Override
public void onAttachedToWindow() {
        super.onAttachedToWindow();

        getWindow().setFormat(PixelFormat.RGBA_8888);
}       
like image 143
Srdjan Grubor Avatar answered Sep 16 '22 15:09

Srdjan Grubor


Could someone explain what the purpose of the following line is please?

options.inPreferredConfig = Bitmap.Config.xxxxxxx

This doesn't seem to have any effect on the bitmap that has been drawn.

Different Bitmap configurations will have different memory footprints. RGB_565 is a 16 bit colour format. ARGB_8888 is a 32 bit format.

Regardless of which getHolder().setFormat(); configuration you've chosen, or how it's being drawn, an ARGB_8888 Bitmap is going to be significantly larger (in memory) than a Bitmap in RGB_565 format.

like image 21
Tyler MacDonell Avatar answered Sep 17 '22 15:09

Tyler MacDonell