How to grayscale a color bitmap?

Widget

Well-Known Member
Licensed User
Longtime User
Is it possible to convert a color bitmap (or bitmapdrawable) into black and white? Unfortunately I don't think B4A supports ColorMatrix.

TIA
Widget

Here are some Java solutions I've found:
B4X:
protected Drawable convertToGrayscale(Drawable drawable)
{
    ColorMatrix matrix = new ColorMatrix();
    matrix.setSaturation(0);

    ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);

    drawable.setColorFilter(filter);

    return drawable;
}

or

B4X:
Bitmap grayscaleBitmap = Bitmap.createBitmap(
    colorBitmap.getWidth(), colorBitmap.getHeight(),
    Bitmap.Config.RGB_565);

Canvas c = new Canvas(grayscaleBitmap);
Paint p = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(cm);
p.setColorFilter(filter); 
c.drawBitmap(colorBitmap, 0, 0, p);
 

Widget

Well-Known Member
Licensed User
Longtime User
SSG,
Your MESGraphix library seems to work. No problems on jpg or png files. :sign0060:

I had to figure out the operation of it by reading the XML so you may want to include a simple readme file. Did you use the Reflection library to achieve this?

Widget
 
Upvote 0

ssg

Well-Known Member
Licensed User
Longtime User
Sorry about the missing documentation. It was just a small library, did not want to put too much effort into it just yet :D

The library did not use the reflection library. It is a new library built from scratch using the 2nd piece of code you found.

Cheers!
 
Upvote 0

hbruno

Member
Licensed User
Longtime User
Source code ?

Is it possible to post the source code of this library ? it's a good exercise for understand how make a simple library for B4A... :sign0104:

Another question : How do you find a specific method in the immensity of the google doc ?

Bruno
 
Upvote 0

ssg

Well-Known Member
Licensed User
Longtime User
Is it possible to post the source code of this library ? it's a good exercise for understand how make a simple library for B4A... :sign0104:

Another question : How do you find a specific method in the immensity of the google doc ?

Bruno

Hi Bruno,

I am at work right now and my B4A machine is at home. I will post up the code later today.

I really have no idea on how to find specific methods. I myselft have been looking high and low to do something similar like this library. Good thing Widget found those sample codes :D

Cheers!
 
Upvote 0

ssg

Well-Known Member
Licensed User
Longtime User
As requested, here is the source code in all it's glory!

B4X:
package com.madelephantstudios.MESGraphix;

import android.R.drawable;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.Author;
import anywheresoftware.b4a.BA.DontInheritEvents;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;

@ShortName("MESGraphix") // this is the name as it appear on the IDE
@Author("SSG") // your name
@Version(1f) // the version
@ActivityObject
@DontInheritEvents

public class MESGraphix {
   
   Bitmap bmpGrayscale ;
   
   public Bitmap toGrayscale(Bitmap bmpOriginal)
   {        
       int width, height;
       height = bmpOriginal.getHeight();
       width = bmpOriginal.getWidth();    

       if (bmpGrayscale != null) {
          bmpGrayscale.recycle();
       }
       
       bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
       Canvas c = new Canvas(bmpGrayscale);
       Paint paint = new Paint();
       ColorMatrix cm = new ColorMatrix();
       cm.setSaturation(0);
       ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
       paint.setColorFilter(f);
       c.drawBitmap(bmpOriginal, 0, 0, paint);
       return bmpGrayscale;
   }
      
}
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
SSG,
Thanks again for the library. :cool:

Another feature that would be useful is to control the brightness and contrast of the bitmap which is also done through the ColorMatrix. This could be another method to your class. Example changeContrastBrightness. This can control the contrast and brightness of each color, R,G,B which is kind of neat. It will also work on b&w images of course.

What do you think?

Widget

B4X:
       Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(), bmp
            .getHeight(), bmp.getConfig());
        Canvas canvas = new Canvas(alteredBitmap);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        // Increase Contrast, Slightly Reduce Brightness
        float contrast = 3;
        float brightness = -5;
        cm.set(new float[] { contrast, 0, 0, 0, brightness, 0,
            contrast, 0, 0, brightness, 0, 0, contrast, 0,
            brightness, 0, 0, 0, 1, 0 });
        
        paint.setColorFilter(new ColorMatrixColorFilter(cm));
        Matrix matrix = new Matrix();
        canvas.drawBitmap(bmp, matrix, paint);

This code snippet is from Increase Contrast, Reduce Brightness : Color*«*2D Graphics*«*Android
 
Upvote 0

ssg

Well-Known Member
Licensed User
Longtime User
Hi Widget,

Would you like to give the library development a try? It will help you later on a lot more in future development.

One could very easily make a very nice image editor with the functionalities available in colormatrix :D

Give the library development a go, i will try to help along if you get stuck. I am just starting off too with Java, and now it feels real good that I can extend B4A in many many ways :D

Cheers!
 
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
SSG,
Sure.

I thought you were going to release a graphics library for the community and I didn't want to step on your toes. ;)

I'll take a look at creating a Java library.

Widget
 
Upvote 0

ssg

Well-Known Member
Licensed User
Longtime User
Upvote 0

Widget

Well-Known Member
Licensed User
Longtime User
Awaiting your full graphics library!

It may be a while. :(

I see 'your' MESGraphix library converts the image to b&w ok, but it changes the transparent background of the image to black. Bummer. :sign0137:

The reason I'm doing all this is to handle the bitmap button states without having to create different bitmaps for disabled and down states. I have the button's down state working great and I thought changing the button bitmap to b&w would work for the disabled state. But today I realize the rounded button changes to a black rectangle when it is converted to b&w which looks ugly. So I am back to the drawing board.

I don't know why B4A doesn't implement states for bitmap images in the first place, and generate the necessary state bitmaps for Down and Disabled.

Using a graphics package to create duplicate buttons for each state is going to be a nightmare because buttons may be redesigned throughout the project. The customer may not like the shape, size, or color of the buttons and the buttons may have to be redesigned. I don't relish designing and maintaining 3 times more buttons than I really need.

There are 3 possible solutions:
1) Fix the b/w code so the transparent background stays transparent, and maybe add brightness/contrast options to lighten the disabled button.

2) Hide all disabled buttons. :confused:

3) Design only 3 buttons: Down, Up, Disabled and don't put anything on the buttons. I'll call this the button backgrounds. Then design transparent bitmaps to fit on the buttons. This dramatically reduces the amount of work designing buttons at the expense of slightly trickier code at startup (to display two images on the button).

I'll have to mull it over for a bit to see which is the best option.

Widget
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
Maybe bugreport to the lib:

Dim BM As Bitmap, Wid, Ht As Int
BM.initialize(File.DirAssets, "picture.jpg") '200 x 200 pixels
BM = BMP.toGrayscale(BM)

Grayscale result of the picture is also 200 x 200 pixels, but contain the left-top scaled up corner of the picture.
 
Upvote 0
Top