hpique
hpique

Reputation: 120344

White is not white

When dealing with some bitmaps in Android I noticed that the white used in views is not always the same white rendered on bitmaps. Consider this screenshot.

enter image description here

The background white is from a view with white background color.

The foreground "white" is from a white bitmap decoded from the SD card, displayed in an ImageView. This bitmap is decoded using RGB_565 as follows:

BitmapFactory.Options resample = new BitmapFactory.Options();
resample.inPreferredConfig = Config.RGB_565;
resample.inSampleSize = sampleSize;
return BitmapFactory.decodeFile(filePath, resample);

For reference, here's the bitmap.

Why is this and how can it be fixed?

Upvotes: 9

Views: 2381

Answers (6)

MorZa
MorZa

Reputation: 2325

You can change

resample.inPreferredConfig = Config.RGB_565; 

to

resample.inPreferredConfig = Config.ARGB_8888;

But please note that RGB_565 contributes to a better performance, as described here: https://medium.com/@ali.muzaffar/performance-improvement-and-bitmap-pooling-in-android-f97b380cf965#:~:text=ARGB_8888%20has%2032%2Dbit%20color,faster%20to%20render%20as%20well.

Upvotes: 0

ChristophK
ChristophK

Reputation: 3223

Here's what solved this for me:

You need to set the screen density to prevent the bitmap factory from rescaling your bitmap. This is done with the following code:

DisplayMetrics displayMetrics=new DisplayMetrics();
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(displayMetrics);
resample.inScreenDensity = displayMetrics.densityDpi;

Upvotes: 0

Vic Vuci
Vic Vuci

Reputation: 7051

Try setting getWindow().setFormat(PixelFormat.RGB_565) in your onCreate.

The default format seems to change based on SDK version and device type, so just force it to stay at RGB_565

Upvotes: 2

brk3
brk3

Reputation: 1554

Had a very similar if not exact same problem, even setting inPreferredConfig to ARGB_8888 didn't help.

From what I can glean from: http://android.nakatome.net/2010/04/bitmap-basics.html

the problem is Android automatically dithers 24 bit images down to 16 bit, which can mess with the colors. The link mentions you can disable this by either adding an alpha channel to your image, or loading it from the raw directory instead of as a resource.

Seen as neither of these were an option for me I found the following finally worked:

Paint ditherPaint = new Paint();
ditherPaint.setDither(true);
canvas.drawBitmap(mDrawable.getBitmap(), null, 
                  mDrawable.getBounds(), ditherPaint);

Here mDrawable is of type BitmapDrawable.

Upvotes: 1

smok
smok

Reputation: 1717

I have the same issue and after some experiments I noticed that commenting <uses-sdk> solves the problem. Any value for android:minSdkVersion above 3 will make this effect appear (removing <uses-sdk> tag effectively changes minSdkVersion to 1.

Upvotes: 3

Joseph Earl
Joseph Earl

Reputation: 23442

It may be a difference between the image type and the Bitmap the ImageView is rendering on, see Bitmap.Config. Load your image in different modes and see if that helps. Take a look at Bitmap quality and banding for more info.

Upvotes: 0

Related Questions