androidimagebitmapdepthbpp

Android: Save Bitmap object as a bmp (1bpp) file format


Based on this question asked by @ben75: Android : save a Bitmap to bmp file format

My question now is: How can I have a BMP image with the depth of 1 bit per pixel (Black & White)?


Solution

  • Answering my own question...

    After some tough search all over the web I realized I had to create 2 things: a bitmap black and white - and did that using the approach of making all 0's for colors below 128 and 255's for the rest, like this (this is C# code, as I'm using Xamarin to code my app):

    private void ConvertArgbToOneColor (Bitmap bmpOriginal, int width, int height){
            int pixel;
            int k = 0;
            int B=0,G=0,R=0;
            try{
                for(int x = 0; x < height; x++) {
                    for(int y = 0; y < width; y++, k++) {
                        pixel = bmpOriginal.GetPixel(y, x);
    
                        R = Color.GetRedComponent(pixel);
                        G = Color.GetGreenComponent(pixel);
                        B = Color.GetBlueComponent(pixel);
    
                        R = G = B = (int)(0.299 * R + 0.587 * G + 0.114 * B);
                        if (R < 128) {
                            m_imageArray[k] = 0;
                        } else {
                            m_imageArray[k] = 1;
                        }
                    }
                    if(m_dataWidth>width){
                        for(int p=width;p<m_dataWidth;p++,k++){
                            m_imageArray[k]=1;
                        }
                    }
                }
            }catch (Exception e) {
                System.Console.WriteLine ("Converting to grayscale ex: " + e.Message);
            }
        }
    

    Then get the byteArray of Monochrome image:

    int length = 0;
    for (int i = 0; i < m_imageArray.Length; i = i + 8) {
        byte first = m_imageArray[i];
        for (int j = 0; j < 7; j++) {
            byte second = (byte) ((first << 1) | m_imageArray[i + j]);
            first = second;
        }
        m_rawImage[length] = first;
        length++;
    }
    

    And finally create the bitmap "by hand" using the following variables and placing them into a FileOutputStream to save the file:

        private static int FILE_HEADER_SIZE = 14;
        private static int INFO_HEADER_SIZE = 40;
    
        // Bitmap file header
        private byte[] bfType = { (byte) 'B', (byte) 'M' };
        private int bfSize = 0;
        private int bfReserved1 = 0;
        private int bfReserved2 = 0;
        private int bfOffBits = FILE_HEADER_SIZE + INFO_HEADER_SIZE + 8;
    
        // Bitmap info header
        private int biSize = INFO_HEADER_SIZE;
        private int biWidth = 0;
        private int biHeight = 0;
        private int biPlanes = 1;
        private int biBitCount = 1;
        private int biCompression = 0;
        private int biSizeImage = 0;
        private int biXPelsPerMeter = 0x0;
        private int biYPelsPerMeter = 0x0;
        private int biClrUsed = 2;
        private int biClrImportant = 2;
    
        // Bitmap raw data
        private byte[] bitmap;
    
        // Scanlinsize;
        int scanLineSize = 0;
    
        // Color Pallette to be used for pixels.
        private byte[] colorPalette = { 0, 0, 0, (byte) 255, (byte) 255,
            (byte) 255, (byte) 255, (byte) 255 };