10

I'm trying to mask Bitmap with gradient alpha at bottom. Gradient size are fixed and independed of Bitmap size. But it draws incorrect: bottom of gradient at top, than top. What's wrong?

enter image description here

There is sample code:

final int GRADIENT_HEIGHT = 32;

public Bitmap addGradient(Bitmap src) {
    int w = src.getWidth();
    int h = src.getHeight();
    Bitmap overlay = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(overlay);

    canvas.drawBitmap(src, 0, 0, null);

    Paint paint = new Paint();
    LinearGradient shader = new LinearGradient(0, 0, 0, GRADIENT_HEIGHT, 0xFFFFFFFF, 0x00FFFFFF, TileMode.REPEAT);
    paint.setShader(shader);
    paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
    canvas.drawRect(0, h - GRADIENT_HEIGHT, w, h, paint);

    return overlay;
}

Thanks!

Ganster41
  • 486
  • 3
  • 14

1 Answers1

7

Change your LinearGradient to this:

    LinearGradient shader = new LinearGradient(0,  h - GRADIENT_HEIGHT, 0, h, 0xFFFFFFFF, 0x00FFFFFF, Shader.TileMode.CLAMP);
Jens Zalzala
  • 2,546
  • 1
  • 22
  • 28
  • Yes, it's working fine. Can you explain your answer, please? Or may be it documented somewhere? I can't find... – Ganster41 May 15 '14 at 06:53
  • 1
    Even though your drawRect call was drawing in the right spot, it doesn't remap the position of the gradient. So the top of the box was not position 0,0 for the gradient, as you expected, but instead was still h-GRADIENT_HEIGHT. So the only reason you were seeing anything is because you were using TileMode.REPEAT. – Jens Zalzala May 15 '14 at 16:45
  • Is it possible to use this on a RelativeLayout instead of a Bitmap? – Henning Hall May 27 '18 at 19:47
  • @HenningHall you may be better off using a gradient drawable as a foreground image on a layout. – Jens Zalzala Jun 05 '18 at 21:01
  • Yeah, but it won't work in cases where the background color is unknown or in multiple colors right? – Henning Hall Jun 06 '18 at 07:07