Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grayscaled bitmaps in android

I have an array of bytes that correspond to a "grayscaled bitmap" (one byte->one pixel), and I need to create a PNG file for this image.

The method below works, but the png created is HUGE, as the Bitmap I am using is an ARGB_8888 bitmap, which takes 4 bytes per pixel instead of 1 byte.

I haven't been able to make it work with other Bitmap.Config different than ARGB_8888. Maybe ALPHA_8 is what I need, but I have not been able to make it work.

I have also tried the toGrayScale method which is included in some other posts (Convert a Bitmap to GrayScale in Android), but I have the same issue with the size.

public static boolean createPNGFromGrayScaledBytes(ByteBuffer grayBytes, int width,
        int height,File pngFile) throws IOException{

    if (grayBytes.remaining()!=width*height){
        Logger.error(Tag, "Unexpected error: size mismatch [remaining:"+grayBytes.remaining()+"][width:"+width+"][height:"+height+"]", null);
        return false;
    }
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    // for each byte, I set it in three color channels.
    int gray,color;
    int x=0,y=0;        
    while(grayBytes.remaining()>0){

        gray = grayBytes.get();
        // integer may be negative as byte is signed. make them positive. 
        if (gray<0){gray+=256;}

        // for each byte, I set it in three color channels.
        color= Color.argb(-1, gray, gray, gray);


        bitmap.setPixel(x, y, color);
        x++;
        if (x==width){
            x=0;
            y++;
        }           
    }
    FileOutputStream fos=null;

    fos = new FileOutputStream(pngFile);
    boolean result= bitmap.compress(Bitmap.CompressFormat.PNG,100,fos);
    fos.close();
    return result;
}       

EDIT: Link to the generated file (it may look nonsense, but is just created with randon data). http://www.tempfiles.net/download/201208/256402/huge_png.html

Any help will be greatly appreciated.

like image 617
richardtz Avatar asked Jul 18 '26 15:07

richardtz


2 Answers

As you've noticed, saving a grayscale image as RGB is expensive. If you have luminance data then it would be better to save as a Grayscale PNG rather than an RGB PNG.

The bitmap and image functionality available in the Android Framework is really geared towards reading and writing image formats that are supported by the framework and UI components. Grayscale PNG is not included here.

If you want to save out a Grayscale PNG on Android then you'll need to use a library like http://code.google.com/p/pngj/

like image 187
Error 454 Avatar answered Jul 20 '26 03:07

Error 454


If you use OPENCV for Android library, you can use the library to save a binary data to a png file. My way is: in jni part, set Mat whose data begin with the byte array:

jbyte* _ByteArray_BrightnessImgForOCR = env->GetByteArrayElements(ByteArray_BrightnessImgForOCR, 0);
Mat img(ByteArray_BrightnessImgForOCR_h, ByteArray_BrightnessImgForOCR_w, CV_8UC1, (unsigned char *) _ByteArray_BrightnessImgForOCR);

And then write it to a png file.

imwrite("/mnt/sdcard/binaryImg_forOCR.png", img);

Of course, you need to take some time to get yourself familiar with OpenCV and Java native coding. Following OpenCV for Android examples, it is fast to learn.

like image 22
user1914692 Avatar answered Jul 20 '26 05:07

user1914692



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!