12

How do I take an existing bitmap, say

Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.somebitmap);

and write a method that returns a darkened version of the bitmap?

private Bitmap darkenBitMap(Bitmap bm) { }

I've been trying to use Paint and Canvas with no results so far.

the_prole
  • 8,275
  • 16
  • 78
  • 163
  • You might want to use a filter, if you don't want to permanently darken it and save to disk, share, etc... Here are few references, http://gamedev.stackexchange.com/a/5394 http://stackoverflow.com/a/3499103/892500 – Gökhan Barış Aker Jan 02 '16 at 05:29

5 Answers5

39

I got it finally. Hope it helps someone else.

private Bitmap darkenBitMap(Bitmap bm) {

    Canvas canvas = new Canvas(bm);
    Paint p = new Paint(Color.RED);
    //ColorFilter filter = new LightingColorFilter(0xFFFFFFFF , 0x00222222); // lighten
    ColorFilter filter = new LightingColorFilter(0xFF7F7F7F, 0x00000000);    // darken
    p.setColorFilter(filter);
    canvas.drawBitmap(bm, new Matrix(), p);

    return bm;
}
the_prole
  • 8,275
  • 16
  • 78
  • 163
2

To make view darker.

canvas.drawARGB(200, 0, 0, 0);

Short and simple :)

oxied
  • 1,773
  • 19
  • 14
1
private Bitmap darkenBitMap(Bitmap bm) {
    Canvas canvas = new Canvas(bm);
    canvas.drawARGB(1,0,0,0);
    canvas.drawBitmap(bm, new Matrix(), new Paint());
    return bm;
}
  • 2
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. Please read why [it isn't wise to post code-only answers](https://meta.stackexchange.com/a/148274/341145) – Sᴀᴍ Onᴇᴌᴀ Sep 27 '17 at 21:49
0

Building up on the_prole's answer, here is a function that can make a transition of darker bitmap to lighter one. All you have to do is pass a number between 0 and 100 (0 being darker and 100 being lighter).

public void grayscaleImage(Bitmap bitmap, int lighten)
{
    Bitmap bmpGrayscale = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(bmpGrayscale);

    Paint grayscalePaint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0);
    grayscalePaint.setColorFilter(new ColorMatrixColorFilter(cm));
    c.drawBitmap(bitmap, new Matrix(), grayscalePaint);

    ArgbEvaluator evaluator = new ArgbEvaluator();

    float fraction = lighten / 100.0F;

    int mul = (int) evaluator.evaluate(fraction, 0xFF7F7F7F, 0xFFFFFFFF);
    int add = (int) evaluator.evaluate(fraction, 0x00000000, 0x00222222);

    Paint lighteningPaint = new Paint();
    lighteningPaint.setColorFilter(new LightingColorFilter(mul, add));
    c.drawBitmap(bmpGrayscale, new Matrix(), lighteningPaint);

    setImageBitmap(bmpGrayscale);
}
Bugs Happen
  • 2,169
  • 4
  • 33
  • 59
-1

Here is a sample that iterates over each pixel.

/**
 * @param bitmap a mutable bitmap instance.
 */
private void darkenBitmap(Bitmap bitmap) {
    int height = bitmap.getHeight();
    int width = bitmap.getWidth();
    int pixel;

    // Iterate over each row (y-axis)
    for (int y = 0; y < height; y++) {
        // and each column (x-axis) on that row
        for (int x = 0; x < width; x++) {
            pixel = bitmap.getPixel(x, y);

            // TODO: Modify your pixel here. For samples, http://stackoverflow.com/questions/4928772/android-color-darker

            bitmap.setPixel(x, y, pixel);
        }
    }
}

The method requires mutable bitmap, so you will probably need to load your bitmap with BitmapFactory options. e.g.,

BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.somebitmap, options);

You might as well create a new mutable bitmap inside that method, call setPixel(...) on that and return it. But, I will strongly suggest avoiding that kind of memory allocation if possible.

Gökhan Barış Aker
  • 4,445
  • 5
  • 25
  • 35