Android bitmap to bufferedimage

10,278

I've used this class many times to convert diferent bitmaps to bufferedimages

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.io.IOException;
import java.io.InputStream;

/**
 * Utility class for loading windows bitmap files
 * <p>
 * Based on code from author Abdul Bezrati and Pepijn Van Eeckhoudt
 */
public class BitmapLoader {

    /**
     * Static method to load a bitmap file based on the filename passed in.
     * Based on the bit count, this method will either call the 8 or 24 bit
     * bitmap reader methods
     *
     * @param file The name of the bitmap file to read
     * @throws IOException
     * @return A BufferedImage of the bitmap
     */
    public static BufferedImage loadBitmap(String file) throws IOException {
        BufferedImage image;
        InputStream input = null;
        try {
            input = ResourceRetriever.getResourceAsStream(file);

            int bitmapFileHeaderLength = 14;
            int bitmapInfoHeaderLength = 40;

            byte bitmapFileHeader[] = new byte[bitmapFileHeaderLength];
            byte bitmapInfoHeader[] = new byte[bitmapInfoHeaderLength];

            input.read(bitmapFileHeader, 0, bitmapFileHeaderLength);
            input.read(bitmapInfoHeader, 0, bitmapInfoHeaderLength);

            int nSize = bytesToInt(bitmapFileHeader, 2);
            int nWidth = bytesToInt(bitmapInfoHeader, 4);
            int nHeight = bytesToInt(bitmapInfoHeader, 8);
            int nBiSize = bytesToInt(bitmapInfoHeader, 0);
            int nPlanes = bytesToShort(bitmapInfoHeader, 12);
            int nBitCount = bytesToShort(bitmapInfoHeader, 14);
            int nSizeImage = bytesToInt(bitmapInfoHeader, 20);
            int nCompression = bytesToInt(bitmapInfoHeader, 16);
            int nColoursUsed = bytesToInt(bitmapInfoHeader, 32);
            int nXPixelsMeter = bytesToInt(bitmapInfoHeader, 24);
            int nYPixelsMeter = bytesToInt(bitmapInfoHeader, 28);
            int nImportantColours = bytesToInt(bitmapInfoHeader, 36);

            if (nBitCount == 24) {
                image = read24BitBitmap(nSizeImage, nHeight, nWidth, input);
            } else if (nBitCount == 8) {
                image = read8BitBitmap(nColoursUsed, nBitCount, nSizeImage, nWidth, nHeight, input);
            } else {
                System.out.println("Not a 24-bit or 8-bit Windows Bitmap, aborting...");
                image = null;
            }
        } finally {
            try {
                if (input != null)
                    input.close();
            } catch (IOException e) {
            }
        }
        return image;
    }

    /**
     * Static method to read a 8 bit bitmap
     *
     * @param nColoursUsed Number of colors used
     * @param nBitCount The bit count
     * @param nSizeImage The size of the image in bytes
     * @param nWidth The width of the image
     * @param input The input stream corresponding to the image
     * @throws IOException
     * @return A BufferedImage of the bitmap
     */
    private static BufferedImage read8BitBitmap(int nColoursUsed, int nBitCount, int nSizeImage, int nWidth, int nHeight, InputStream input) throws IOException {
        int nNumColors = (nColoursUsed > 0) ? nColoursUsed : (1 & 0xff) << nBitCount;

        if (nSizeImage == 0) {
            nSizeImage = ((((nWidth * nBitCount) + 31) & ~31) >> 3);
            nSizeImage *= nHeight;
        }

        int npalette[] = new int[nNumColors];
        byte bpalette[] = new byte[nNumColors * 4];
        readBuffer(input, bpalette);
        int nindex8 = 0;

        for (int n = 0; n < nNumColors; n++) {
            npalette[n] = (255 & 0xff) << 24 |
                    (bpalette[nindex8 + 2] & 0xff) << 16 |
                    (bpalette[nindex8 + 1] & 0xff) << 8 |
                    (bpalette[nindex8 + 0] & 0xff);

            nindex8 += 4;
        }

        int npad8 = (nSizeImage / nHeight) - nWidth;
        BufferedImage bufferedImage = new BufferedImage(nWidth, nHeight, BufferedImage.TYPE_INT_ARGB);
        DataBufferInt dataBufferByte = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer());
        int[][] bankData = dataBufferByte.getBankData();
        byte bdata[] = new byte[(nWidth + npad8) * nHeight];

        readBuffer(input, bdata);
        nindex8 = 0;

        for (int j8 = nHeight - 1; j8 >= 0; j8--) {
            for (int i8 = 0; i8 < nWidth; i8++) {
                bankData[0][j8 * nWidth + i8] = npalette[((int) bdata[nindex8] & 0xff)];
                nindex8++;
            }
            nindex8 += npad8;
        }

        return bufferedImage;
    }

    /**
     * Static method to read a 24 bit bitmap
     *
     * @param nSizeImage size of the image  in bytes
     * @param nHeight The height of the image
     * @param nWidth The width of the image
     * @param input The input stream corresponding to the image
     * @throws IOException
     * @return A BufferedImage of the bitmap
     */
    private static BufferedImage read24BitBitmap(int nSizeImage, int nHeight, int nWidth, InputStream input) throws IOException {
        int npad = (nSizeImage / nHeight) - nWidth * 3;
        if (npad == 4 || npad < 0)
            npad = 0;
        int nindex = 0;
        BufferedImage bufferedImage = new BufferedImage(nWidth, nHeight, BufferedImage.TYPE_4BYTE_ABGR);
        DataBufferByte dataBufferByte = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer());
        byte[][] bankData = dataBufferByte.getBankData();
        byte brgb[] = new byte[(nWidth + npad) * 3 * nHeight];

        readBuffer(input, brgb);

        for (int j = nHeight - 1; j >= 0; j--) {
            for (int i = 0; i < nWidth; i++) {
                int base = (j * nWidth + i) * 4;
                bankData[0][base] = (byte) 255;
                bankData[0][base + 1] = brgb[nindex];
                bankData[0][base + 2] = brgb[nindex + 1];
                bankData[0][base + 3] = brgb[nindex + 2];
                nindex += 3;
            }
            nindex += npad;
        }

        return bufferedImage;
    }

    /**
     * Converts bytes to an int
     *
     * @param bytes An array of bytes
     * @param index
     * @returns A int representation of the bytes
     */
    private static int bytesToInt(byte[] bytes, int index) {
        return (bytes[index + 3] & 0xff) << 24 |
                (bytes[index + 2] & 0xff) << 16 |
                (bytes[index + 1] & 0xff) << 8 |
                bytes[index + 0] & 0xff;
    }

    /**
     * Converts bytes to a short
     *
     * @param bytes An array of bytes
     * @param index
     * @returns A short representation of the bytes
     */
    private static short bytesToShort(byte[] bytes, int index) {
        return (short) (((bytes[index + 1] & 0xff) << 8) |
                (bytes[index + 0] & 0xff));
    }

    /**
     * Reads the buffer
     *
     * @param in An InputStream
     * @param buffer An array of bytes
     * @throws IOException
     */
    private static void readBuffer(InputStream in, byte[] buffer) throws IOException {
        int bytesRead = 0;
        int bytesToRead = buffer.length;
        while (bytesToRead > 0) {
            int read = in.read(buffer, bytesRead, bytesToRead);
            bytesRead += read;
            bytesToRead -= read;
        }
    }
}
Share:
10,278
wombatatat
Author by

wombatatat

Updated on June 04, 2022

Comments

  • wombatatat
    wombatatat almost 2 years

    Is there a simple way to convert a Bitmap image datatype to a BufferedImage?

    I need a bitmap image scaled to 224*224 to be converted into a BufferedImage in order to do pixel comparisons between two BufferedImages.

    I've been trying to develop a simple facial recognition class that would take 2 bitmap images (taken from the android camera) and compare them using a local binary pattern recognition algorithm. source code for image comparison:

    import java.awt.image.*;
    import java.awt.color.ColorSpace;
    
    public class ImageEncode {
    
     public static boolean facialRecognition(BufferedImage i, BufferedImage i2) {
    
      int currentPixelValue, newPixelValue;
      int[][] imageArray = new int[224][224], imageArray2 = new int[224][224], lbpArray = new int[224][224], lbpArray2 = new int[224][224], histogram = new int[9][256], histogram2 = new int[9][256];
    
    
    
      //input pictures, resize to 224x224
      BufferedImage image = i;
      BufferedImage image2 = i2;
    
      //convert to gray scale
      ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
      ColorConvertOp op = new ColorConvertOp(cs, null);
      image = op.filter(image, null);
      image2=op.filter(image2, null);
    
      //gaussian filter
      Kernel kernel = new Kernel(3,3,
        new float[] {
         1f/9f, 1f/9f, 1f/9f,
         1f/9f, 1f/9f, 1f/9f,
         1f/9f, 1f/9f, 1f/9f});
      BufferedImageOp op2 = new ConvolveOp(kernel);
      image = op2.filter(image, null);
      image2= op2.filter(image2, null);
    
      //convert images to pixel value array
      for(int row=0; row<=223; row++){
       for(int col=0; col<=223; col++){
        imageArray[row][col]=image.getRGB(row, col);
        imageArray2[row][col]=image2.getRGB(row, col);
       }
      }  
    
      //perform lbp calculations  
      for(int row=1; row<223; row++){
       for(int col=1; col<223; col++){
        currentPixelValue=imageArray[row][col];
        newPixelValue=0;
        if(imageArray[row-1][col-1]>currentPixelValue) newPixelValue=newPixelValue+1;
        if(imageArray[row-1][col]>currentPixelValue) newPixelValue=newPixelValue+2;
        if(imageArray[row-1][col+1]>currentPixelValue) newPixelValue=newPixelValue+4;
        if(imageArray[row][col+1]>currentPixelValue) newPixelValue=newPixelValue+8;
        if(imageArray[row+1][col+1]>currentPixelValue) newPixelValue=newPixelValue+16;
        if(imageArray[row+1][col]>currentPixelValue) newPixelValue=newPixelValue+32;
        if(imageArray[row+1][col-1]>currentPixelValue) newPixelValue=newPixelValue+64;
        if(imageArray[row][col-1]>currentPixelValue) newPixelValue=newPixelValue+128;
        lbpArray[row][col]=newPixelValue;
       }
      }
    
      for(int row=1; row<223; row++){
       for(int col=1; col<223; col++){
        currentPixelValue=imageArray2[row][col];
        newPixelValue=0;
        if(imageArray2[row-1][col-1]>currentPixelValue) newPixelValue=newPixelValue+1;
        if(imageArray2[row-1][col]>currentPixelValue) newPixelValue=newPixelValue+2;
        if(imageArray2[row-1][col+1]>currentPixelValue) newPixelValue=newPixelValue+4;
        if(imageArray2[row][col+1]>currentPixelValue) newPixelValue=newPixelValue+8;
        if(imageArray2[row+1][col+1]>currentPixelValue) newPixelValue=newPixelValue+16;
        if(imageArray2[row+1][col]>currentPixelValue) newPixelValue=newPixelValue+32;
        if(imageArray2[row+1][col-1]>currentPixelValue) newPixelValue=newPixelValue+64;
        if(imageArray2[row][col-1]>currentPixelValue) newPixelValue=newPixelValue+128;
        lbpArray2[row][col]=newPixelValue;
       }
      }
    
      //create histograms
      for(int row=1; row<=222; row++){
       for(int col=1; col<=222; col++){
        if(row<75 && col<75) histogram[0][imageArray[row][col]]++;
        if(row<75 && col>74 && col<149) histogram[1][imageArray[row][col]]++;
        if(row<75 && col>148 && col<223) histogram[2][imageArray[row][col]]++;
        if(row>74 && row<149 && col<75) histogram[3][imageArray[row][col]]++;
        if(row>74 && row<149 && col>75 && col<149) histogram[4][imageArray[row][col]]++;
        if(row>74 && row<149 && col>148 && col<223) histogram[5][imageArray[row][col]]++;
        if(row>148 && row<223 && col<75) histogram[6][imageArray[row][col]]++;
        if(row>148 && row<223 && col>74 && col<149) histogram[7][imageArray[row][col]]++;
        if(row>148 && row<223 && col>148 && col<223) histogram[8][imageArray[row][col]]++;
       }
      }  
    
      for(int row=1; row<=222; row++){
       for(int col=1; col<=222; col++){
        if(row<75 && col<75) histogram2[0][imageArray2[row][col]]++;
        if(row<75 && col>74 && col<149) histogram2[1][imageArray2[row][col]]++;
        if(row<75 && col>148 && col<223) histogram2[2][imageArray2[row][col]]++;
        if(row>74 && row<149 && col<75) histogram2[3][imageArray2[row][col]]++;
        if(row>74 && row<149 && col>75 && col<149) histogram2[4][imageArray2[row][col]]++;
        if(row>74 && row<149 && col>148 && col<223) histogram2[5][imageArray2[row][col]]++;
        if(row>148 && row<223 && col<75) histogram2[6][imageArray2[row][col]]++;
        if(row>148 && row<223 && col>74 && col<149) histogram2[7][imageArray2[row][col]]++;
        if(row>148 && row<223 && col>148 && col<223) histogram2[8][imageArray2[row][col]]++;
       }
      }  
    
      //Compare histograms
      for(int k=0; k<=8; k++){
       for(int j=0; j<=255; j++){
        if((((histogram[k][j])*0.1)+histogram[k][j]) < histogram2[k][j] || (histogram[k][j]-((histogram[k][j])*0.1)) > histogram2[k][j]){
         return false;
        }
       }
      }
    
      return true;
    
     }
    
    }