Convert buffered image to the 2D byte array with the same data

陌路散爱 提交于 2019-12-22 12:12:07

问题


I have written one application for image processing in Java. I have processed the image which is the buffered image and now I want to return the byte[] for that processed image that is I should get the byte array of binarized image.

Here is my code:

public static byte[][] binarizeImage(BufferedImage bfImage){

        int red;
        int newPixel;
        int h ;
        int w ;
        int threshold = otsuTreshold(bfImage);   
          // this function returns the threshold value 199

        BufferedImage binarized = new BufferedImage(bfImage.getWidth(), bfImage.getHeight(), bfImage.getType());

        for(int i=0; i<bfImage.getWidth(); i++) {
        for(int j=0; j<bfImage.getHeight(); j++) {

            // Get pixels
            red = new Color(bfImage.getRGB(i, j)).getRed();
            int alpha = new Color(bfImage.getRGB(i, j)).getAlpha();
            if(red > threshold) {
                newPixel = 255;
            }
            else {
                newPixel = 0;
            }
            newPixel = colorToRGB(alpha, newPixel, newPixel, newPixel);
            binarized.setRGB(i, j, newPixel); 
       }

     }
          Raster raster  = binarized.getData();

    h = raster.getHeight();
    w = raster.getWidth();

    byte[][] binarize_image = new byte[w][h];

    for(int i=0 ; i<w ; i++)
    {
        for(int j=0; j<h ; j++)
        {
            binarize_image[i][j]=raster.getSampleModel();  //error at this line 
        }
   }
   return binarize_image;
}

// Convert R, G, B, Alpha to standard 8 bit
    private static int colorToRGB(int alpha, int red, int green, int blue) {

        int newPixel = 0;
        newPixel += alpha;
        newPixel = newPixel << 8;
        newPixel += red; newPixel = newPixel << 8;
        newPixel += green; newPixel = newPixel << 8;
        newPixel += blue;

        return newPixel;

    }

But it is not working. What should I do to convert that buffered image to byte array for the same image data?


回答1:


I am not sure what the term "binarize" means at this context. You seem to just want to filter the image (i.e. cutt-off the red channel based on some threshold) and convert the result to a byte[].

Assuming the above is correct then check the code below. It will convert the image to a byte[] for a 32-bit image. Please take into account the following:

  • You do not need to first filter the image and then convert to byte[]. You can do that during the conversion.
  • "Convert RGB to standard 8-bit" : If you mean 8-bit per color channel then this is ok, but if you mean 8-bit per pixel then you are talking about compression/conversion (i.e. you will probably loose some information/quality) in which case you should provide more information about what you want to achieve.
  • Your resulting byte[] would have a size of 4 * width * height not width * height assuming we are talking about the case of a 32-bit image. If you need to handle other cases you should take into account the available image types supported by the BufferedImage (or at least only the ones you are interested in).

The code below will print information for each converted pixel like below (Note how the red channel is filtered):

[0,0] Converting [ffaaccee] --> [0, cc, ee, ff]

package imageio.byteconversion;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;

public class BufferedImageToBytes {

    private static void log(String s) {
        System.out.println(s);
    }

    private static String toByteString(int color) {
        // Perform a bitwise AND for convenience while printing. 
        // Otherwise Integer.toHexString() interprets values as integers and a negative byte 0xFF will be printed as "ffffffff"
        return Integer.toHexString(color & 0xFF);
    }

    public static void main(String[] args) throws IOException {

        // Load the image. This expects the image to be in the same package with this class 
        InputStream stream = BufferedImageToBytes.class.getResourceAsStream("test.png");
        BufferedImage image = ImageIO.read(stream);
        int iw = image.getWidth();
        int ih = image.getHeight();
        log("Image loaded succesfully, width=" + iw + " height=" + ih);
        stream.close();

        log("Image color model: " + image.getColorModel());
        log("Image sample model: " + image.getSampleModel());
        log("Image raster: " + image.getRaster());

        int bands = image.getSampleModel().getNumBands();
        log("Color bands: " + bands);
        if (bands != 4) {
            throw new RuntimeException("The image does not have 4 color bands. Are you sure this is a 32-bit image?");
        }

        int threshold = 199; // <-- decide your threshold here

        byte bytes[] = new byte[4 * iw * ih];
        int index = 0;

        // note that image is processed row by row top to bottom
        for(int y = 0; y < ih; y++) {
            for(int x = 0; x < iw; x++) {

                // returns a packed pixel where each byte is a color channel
                // order is the default ARGB color model
                int pixel = image.getRGB(x, y);

                // Get pixels
                int alpha = (pixel >> 24) & 0xFF;
                int red = (pixel >> 16) & 0xFF;
                int green = (pixel >> 8) & 0xFF;
                int blue = pixel & 0xFF;

                // perform filtering here depending on threshold 
                if (red > threshold) {
                   red = 255;
                } else {
                    red = 0;
                }

                log("[" + x + "," + y + "]" + " Converting [" + Integer.toHexString(pixel)  + "] --> ["
                        + toByteString(red) + ", " + toByteString(green) + ", " 
                        + toByteString(blue) + ", " + toByteString(alpha)
                        + "]");

                bytes[index++] = (byte) red;
                bytes[index++] = (byte) green;
                bytes[index++] = (byte) blue;
                bytes[index++] = (byte) alpha;
           }
        }
    }
}



回答2:


Why don't you try to use libs as Catalano Framework. http://code.google.com/p/catalano-framework/

FastBitmap fb = new FastBitmap("c:\\files\\image.jpg");
fb.toGrayscale();

OtsuThreshold otsu = new OtsuThreshold();
otsu.applyInPlace(fb);

int[][] image = new int[fb.getHeight()][fb.getWidth()];
fb.toArrayGray(image);



回答3:


How about:

BufferedImage input;

BufferedImage binary = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_BYTE_BINARY);

Graphics2D g = binary.createGraphics();
try {
    g.drawImage(input, 0, 0, null);
}
finally {
   g.dispose();
}

It will not use your otsuTreshold, and it will (probably) dither the image, but it will do the job of making it binary (black/white only), using a minimal amount of memory.




回答4:


  try {
                  // get the BufferedImage, using the ImageIO class
                  Bitmap image = 
                    BitmapFactory.decodeStream(getAssets()
                            .open("aa.bmp"));
                  marchThroughImage(image);
                } catch (IOException e) {
                  System.err.println(e.getMessage());
                }
        }
    });


}
public void printPixelARGB(int pixel) {
    int alpha = (pixel >> 24) & 0xff;
    int red = (pixel >> 16) & 0xff;
    int green = (pixel >> 8) & 0xff;
    int blue = (pixel) & 0xff;
    System.out.println("argb: " + alpha + ", " + red + ", " + green + ", " + blue);
  }
private void marchThroughImage(Bitmap image) {
    int w = image.getWidth();
    int h = image.getHeight();
    System.out.println("width, height: " + w + ", " + h);

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        System.out.println("x,y: " + j + ", " + i);
        int pixel = image.getPixel(j, i);
        printPixelARGB(pixel);
        System.out.println("");
      }
    }
  }


来源:https://stackoverflow.com/questions/18503412/convert-buffered-image-to-the-2d-byte-array-with-the-same-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!