16

I'm trying to place a background in my activity, but the image quality is not the expected.

The image has a simple gradient above blue stripes, and currently looks like this:

LinearLayout background

My activity layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/background_register"
    android:drawingCacheQuality="high" >
</LinearLayout>

The background descriptor (drawable/background_register):

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:tileMode="repeat"
    android:gravity="center"
    android:src="@drawable/background_blue_565" />

Currently I have an XML file describing a BitmapDrawable, which is the actitivy's LinearLayout background. But I've tried everything I found so far. Enabled dither, antialias, tile, RGBA_8888 modes... You name it. Does anyone have a different solution or idea I could try? I'd be very grateful.

Btw, I'm currently developing the app in a Galaxy S II.

gnclmorais
  • 4,897
  • 5
  • 30
  • 41

3 Answers3

42

First of all, make sure that your original image looks good so you're not just getting the problem from there.
Then, in your onCreate() method, do:

code1:

getWindow().getDecorView().getBackground().setDither(true);
getWindow().setFormat(PixelFormat.RGBA_8888);

Deprecated:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER);

And to load your image explicitly as a 32-bit image (RGBA-8888 configuration) add the following where you load your views:

code2:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap gradient = BitmapFactory.decodeResource(getResources(), R.drawable.gradient, options);

findViewById(R.id.main).setBackgroundDrawable(new BitmapDrawable(gradient));


Comparison between different approaches: (these are all screenshots from the resulting application)

My source images (64 colors to the left, 24 bit to the right):
image1 and image2:
64-color24 bit
1: Raw 64-color image (image1) set as background from layout XML:
Raw image
2: The same image (image1), using code1:
Dithered image
3: The same image (image1) using both code1 and code2:
explicit 32bit
4: image2, loaded with code1 and code2 (in this case the dithering is not really important as both the source and destination use 8 bits per color):
higher original quality

Notice how the resulting artifacts in image 3 already exists in the original image.

Note: if anyone knows how to shrink the images down a bit, feel free to edit this post...

Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Jave
  • 31,598
  • 14
  • 77
  • 90
  • Thanks for the fast response! Tried everything you purposed, but no luck at all. The image is fine, looks awesome when I see it in the Android gallery. – gnclmorais Dec 07 '11 at 15:33
  • Are you doing any operations on it in your program or are you just setting it as the background in your xml? This definitely looks like an image compression problem, which have always corrected themselves when increasing the bit depth and/or enabling dither. – Jave Dec 07 '11 at 15:38
  • I'm just setting it the background. I have already updated my question with the layouts, so it could be more clear. – gnclmorais Dec 07 '11 at 16:11
  • Jave, I followed what you wrote (thank you!), and the image currently looks like this: http://bit.ly/w4ErRR As you can see, it's not perfect yet... Still, thank you, it is a little better right now. If you find out a better solution, please share it! – gnclmorais Dec 07 '11 at 16:43
  • Looks much better now :) If I come across a better solution I will update my answer. – Jave Dec 07 '11 at 16:54
  • I updated my answer, and I noticed your source is named "background_blue_565", which I assume is the bit configuration you saved it with? You should try to save a 24/32 bit image and import and see if that helps. Dithering is a good thing, but it can't do everything (case 3 in my answer) . – Jave Dec 08 '11 at 09:04
  • Well, it seems the code you provided, along with one of the thousands of image configurations we tried, worked... So thank you! But this is an awful issue in Android. Terrible indeed. Google should fix this somehow. – gnclmorais Dec 08 '11 at 16:56
6

The problem is your PNG has been converted to 256 colours, open your APK in your ZIP tool of choice and check manually. If that's the case, make sure that your PNG has:

  1. An alpha channel
  2. One pixel which is slightly transparent

This should prevent it from being converted to an indexed palette.

Gareth Davidson
  • 4,857
  • 2
  • 26
  • 45
  • Hi Gaz! It really seems the image is being compressed in the APK, but extracting it from there and displaying it in the Android gallery shows a fine image, with no compression or artefacts issues. Even with the alpha channel and the transparent pixel. – gnclmorais Dec 07 '11 at 15:52
  • 2
    Geez, thanks for that. I was having trouble with one image on my app, just opened the application and it's indeed being converted to a 256-color PNG. The problem is, even with transparency, I still can't get it to export correctly. :/ At least I know the problem now... – zeh Dec 09 '11 at 22:38
0

it looks like an image issue to me. what are the setting you are saving the image and format? It looks like compression artifacts from where I am looking.

Astronaut
  • 6,691
  • 18
  • 61
  • 99
  • Thank you for the fast response! The image is fine, looks awesome when I see it in the Android gallery. Seems like the OS is compressing too much the image, specially when it possesses a gradient. – gnclmorais Dec 07 '11 at 15:34
  • The problem is that your image is getting compressed with a very limited pallet probably 256 colors. If there isn't enough information gradients will get degraded like that. Ensure that you are using the same image. Like Gaz proposed open your APK and check it. Also save the image to jpg and try it again. If it works then your problem is your image. – Astronaut Dec 07 '11 at 15:44
  • The image shouldn't be compressed if it uses more than 256 colors, as far as I know, but I could be wrong. – Jave Dec 07 '11 at 15:47
  • Adam Surfari, that cannot be the answer... I opened the APK, I extracted the image, and I opened the image in the Android gallery, and it looked perfect. It must be something the app is doing when applying the image as the LinearLayout background... – gnclmorais Dec 07 '11 at 16:08