LG G watch not displaying 32-bit Images or Gradients with full color depth
Asked Answered
A

1

9

I've been struggling to get gradients to appear smooth on my LG G Watch running Android 5.0.1.

Before you mark as a duplicate, I have tried every answer for several posts (like Why android lose image quality when displaying a png file?, Is it possible to dither a gradient drawable?, android:dither="true" does not dither, what's wrong?, Color Banding Android Solution, Color banding and artifacts with gradients despite using RGBA_8888 everywhere, Color banding only on Android 4.0+, Awful background image quality in Android), but none seem to apply.


Here are my steps for creating a gradient

1) Load Sample 'Wearable: Watch View Stub' project from the latest Android SDK

2) Change the rect_background.xml drawable to:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="@dimen/rect_corner_radius"/>
    <gradient android:startColor="@color/light_grey"
        android:endColor="@color/white"
        android:angle="90"/>
</shape>

3) Here is what it looks like on the emulator

enter image description here

4) Here's what it looks like when I do a screen capture from the device: enter image description here

5) But when I look at it in person, there is terrible banding: (it looks far worse in real life; the image doesn't do it justice) enter image description here enter image description here

The following is a simulated image of what it looks like in person (128 colors): enter image description here

I have also tried:

  • Using a png bitmap (24-bit)
  • Using a png bitmap with 1 transparent pixel (32-bit)
  • Using a png bitmap with all semi-transparent pixels (32-bit)
  • Using a png bitmap with reduced bit-depth (256 colors)
  • Using a jpeg with 100 quality.

  • Manually setting PixelFormat to RGBA_8888 in Activity before and after create layout

  • Turning on dithering in the activity
  • Loading the bitmap from code using a custom bitmap loader (setting pixel format, dithering, etc., see Awful background image quality in Android)
  • Turning off any sort of scaling for the ImageView
  • Putting the image in drawable, drawable-hdpi, and raw folders
  • Unzipping the APK and verifying that the image was uncompressed.

All of these show up the same way.


How do I get this to appear correctly on the device?

Is anyone else seeing this issue? According to this site, the LG G Watch has a color-depth or 24-bit, which should be full 8 bits per channel. Normal images on the device appear correct--no noticeable banding.

Anuska answered 30/12, 2014 at 13:18 Comment(3)
I'm able to reproduce the issue on my LG G Watch as well, but it worked fine on the Moto 360. It looks like other developer found the same issue as well code.google.com/p/android/issues/detail?id=74374Swerve
Did you try to set it as a src drawable to an ImageView (and not as a background),and play with the matrix? it might give more insight...Hanlon
@TacB0sS, yes, I tried with an ImageView src and setting the transform as matrix.Anuska
S
4

I was able to generate a smooth gardient on my LG G Watch like this:

Step 1:

Manually set the pixel format to RGB_565

@Override
public void onAttachedToWindow() {
    super.onAttachedToWindow();
    getWindow().setFormat(PixelFormat.RGB_565);
}

Step 2:

You have to deactivate the hardware Acceleration in the Wear AndroidManifest.xml . Add this property to the application tag:

android:hardwareAccelerated="false"

Step 3:

Define a new method to draw your background:

public static Bitmap drawableToBitmap (Drawable drawable, int height, int width) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

Step 4:

Apply it to your layout:

Bitmap bpBackground = drawableToBitmap(getResources().getDrawable(R.drawable.rect_background), 280, 280);
BitmapDrawable bdBackgorund = new BitmapDrawable(getResources(), bpBackground);
myLayout.setBackground(bdBackgorund);

Unfortunately I wasn't able to get it working inside of the WatchViewStub, but I think this probably already helps you solving the problem.

Step 1 & 2 are necessary to get a decent result, Step 3 & 4 increase the quality again.

You can find the whole solution here: https://github.com/lukeisontheroad/WatchViewStubStackOverflowSolution

Swerve answered 4/1, 2015 at 23:38 Comment(13)
What View does the onAttachedToWindow go in? The one with the background?Anuska
I removed the completed WatchFaceStub and applied it directly to my the top FrameLayout in the main_activity.xmlSwerve
Can you also upload the image that you used?Anuska
I didn't use a image, I used the drawable you described in your question (R.drawable.rect_background)Swerve
ahh great. I'll try it out.Anuska
No unfortunately :( Same issue. Just to be sure, I re-cloned the sample Wear Watch View Stub project, changed the rect style in rect_background.xml to the xml in my post, removed everything from inside the main_activity.xml framelayout, gave an id to the framelayout, added the two blocks of code above into the MainActivity.java, commented out the WatchViewStub section in the onCreate of the main activity, and finally added that last block of code after setContentView in onCreate in the main activity. Shows up the same except with the text missing (as expected with no view stub).Anuska
Just for kicks, I started a blank project and got the same results.Anuska
FYI, I'm using SDK 21 with Android 5.0.1Anuska
Let us continue this discussion in chat.Swerve
Glad I was able to help you :)Swerve
I tested it on my watch as well, but it was necessary to set PixelFormat.RGB_565 to get it working. Is it working for you with setting the PixelFormat?Swerve
<gradient android:startColor="@color/black" android:centerColor="@color/white" android:endColor="@color/white" android:angle="90"/> I tried this and the banding came backAnuska
I don't have the watch with me, but try to just add some transparency. Either for black (#FE0000) or white (#FEFFFF). This might solves your problem.Swerve

© 2022 - 2024 — McMap. All rights reserved.