使用相同的数据将缓冲的图像转换为2D字节数组

我在Java中编写了一个图像处理应用程序。 我已经处理了图像,这是缓冲的图像,现在我想返回已处理图像的byte[] ,我应该得到二值化图像的字节数组。

这是我的代码:

 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 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; } 

但它没有用。 如何将缓冲图像转换为字节数组以获取相同的图像数据?

我不确定术语“二值化”在这种情况下意味着什么。 您似乎只想过滤图像(即根据某个阈值切断红色通道)并将结果转换为byte[]

假设以上是正确的,请检查下面的代码。 它会将图像转换为32位图像的byte[] 。 请考虑以下事项:

  • 您不需要先过滤图像然后转换为byte[] 。 您可以在转换期间执行此操作。
  • “将RGB转换为标准8位” :如果你的意思是每个颜色通道 8位那么这是可以的,但如果你的意思是每像素 8位那么你谈论的是压缩/转换(即你可能会丢失一些信息/在这种情况下,您应该提供有关您想要实现的目标的更多信息。
  • 假设我们正在讨论32位图像的情况,那么结果byte[]的大小将为4 * width * height而不是width * height 。 如果您需要处理其他情况,您应该考虑BufferedImage支持的可用图像类型(或者至少只考虑您感兴趣的图像类型)。

下面的代码将打印每个转换像素的信息,如下所示(注意如何过滤红色通道):

[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; } } } } 

为什么不尝试将lib用作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); 

怎么样:

 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(); } 

它不会使用你的otsuTreshold ,它会(可能)抖动图像,但它会使用最少量的内存来完成二进制(仅黑/白)的工作。

  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(""); } } }