3

I am creating a Live Wallpaper and I'm painting to the canvas on every Runnable.run() call with a changing colour and i'm hoping to put a gradient over the top but the gradient i'm creating is banding horribly. After Googling around for a few days I came up with 2 solutions: set the dither to true set the canvas bitmap to ARGB_8888

i've tried doing the first one (set dither to true) on the getWallpaper() accessor and the Paint object but it's not helped (I can't see any dithering at all) so I've tried changing the canvas bitmap but i'm not sure how to actually display it

// _canvasBmp = Bitmap.createBitmap(metrics.widthPixels, metrics.heightPixels, Bitmap.Config.ARGB_8888);

_shadowPaint.setStyle(Paint.Style.FILL);
_shadowPaint.setShader(new RadialGradient(metrics.widthPixels / 2,
metrics.heightPixels / 2, metrics.heightPixels / 2, 0x00000000,0x33000000, Shader.TileMode.CLAMP));
_shadowPaint.setDither(true); // this hasn't seemed to have done anything to fix the banding

// my main rendering method is this (based on the Google live wallpaper example)
void drawFrame()
{
   final SurfaceHolder holder = getSurfaceHolder();

   Canvas c = null;
   try
   {
           c = holder.lockCanvas();
           // c.setBitmap(_canvasBmp);// this was my attempt to update the bitmap to one that was ARGB_8888 but it didn't render at all

           if (c != null)
           {
                   // draw something
                   drawBackground(c);
                   drawTouchPoint(c);
                   drawShading(c);
                   drawBorder(c);

                   getWallpaper().setDither(true); // yet another attempt to get some kind of dithering going to no avail
           }
   }
   finally
   {
           if (c != null)
                   holder.unlockCanvasAndPost(c);
   }

   _handler.removeCallbacks(_drawClock); // _drawClock is the Runnable object

   if (_isVisible)
   {
           _handler.postDelayed(_drawClock, 1000 / 25);
   }
}


private void drawShading(Canvas c)
{
    c.drawRect(_screenBounds, _shadowPaint); // _screenBounds is a Rect set to the _metrics width and height
}

Thanks in advance for your time

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
obie
  • 578
  • 7
  • 23

1 Answers1

4

In your PinupEngine class...

@Override
public void onCreate(SurfaceHolder surfaceHolder) {
  super.onCreate(surfaceHolder);
  surfaceHolder.setFormat(android.graphics.PixelFormat.RGBA_8888);
}

I have found that the LiveWallpaper drawing is slower with the larger bitmap pixel type. I expect it will also use a lot more memory (More than Double). If you can it might pay to try and limit the use of RGBA_8888 if possible. Default is RGB_565 I think, not sure about that.

CatalystNZ
  • 720
  • 7
  • 15
  • 1
    just a quick comment - the default should be PixelFormat.OPAQUE – obie Jul 20 '11 at 16:33
  • @yokees Some (cheaper) devices have screens that are 565, and that means that ultimately the graphics will be converted to that format before display on those devices. Working in 8888 can still be beneficial quality-wise if you can afford the extra CPU/memory use. – Mr. Developerdude May 08 '13 at 11:25