26

How would one go about tinting a Bitmap to a solid color, effectively replacing all pixels that have an alpha > 0 to a given RGB value? In addition how to do the same thing, but keeping the alpha for every pixel? I'm not looking for per-pixel operations as they tend to be slow.

I tried using a ColorMatrixColorFilter and a ColorFilter, which do tint the Bitmap, but they colorize instead of performing a 100% tint.

Will Kru
  • 5,164
  • 3
  • 28
  • 41

4 Answers4

46

I solved this by using a PorterDuffColorFilter

Paint paint = new Paint();
paint.setColorFilter(new PorterDuffColorFilter(targetColor, PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(resource, matrix, paint);
Will Kru
  • 5,164
  • 3
  • 28
  • 41
  • 5
    If you wonder which `PorterDuff.Mode` should you choose, there is a great article about Porter-Duff rules http://www.ibm.com/developerworks/java/library/j-mer0918/ – tomrozb Apr 28 '13 at 11:56
41

Just to give a more complete answer.

This will take a bitmap and output a new tinted bitmap:

public static Bitmap tintImage(Bitmap bitmap, int color) {
    Paint paint = new Paint();
    paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
    Bitmap bitmapResult = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmapResult);
    canvas.drawBitmap(bitmap, 0, 0, paint);
    return bitmapResult;
}
joaomgcd
  • 5,287
  • 4
  • 28
  • 39
  • 2
    `color` must be in ARGB format, like `color = 0xFF0000FF` to tint the image pure blue. If you use `color = 0x0000FF` it will set the image to completely transparent, because the alpha part = 0x00. – Mr-IDE Nov 22 '17 at 17:31
  • make sure to pass ContextCompat.getColor(context, R.color.YOUR_COLOR) – SilverTech Jan 22 '23 at 13:15
  • For some reason this moves the drawn bitmap to right+bottom a pixel or two, so the bottom&right sides of it are being cut. How come? – android developer Mar 23 '23 at 09:14
4

If your bitmap is a drawable that you want to use in a layout, then you can make a new drawable (.xml) that references your original drawable (e.g .png).

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/plus"
     android:tint="#2c53e5" />
Johan Franzén
  • 2,355
  • 1
  • 17
  • 15
0

Kotlin solution, because for some reason converting the other solutions caused a cut in the bitmap result:

fun getTintedBitmap(inputBitmap: Bitmap, @ColorInt color: Int): Bitmap {
    val paint = Paint()
    paint.colorFilter = PorterDuffColorFilter(color, Mode.SRC_IN)
    val width = inputBitmap.width
    val height = inputBitmap.height
    val result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(result)
    canvas.drawBitmap(inputBitmap, null, Rect(0, 0, width, height), paint)
    return result
}
android developer
  • 114,585
  • 152
  • 739
  • 1,270