androidwear-osbit-depth

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


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:

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.


Solution

  • 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