我在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<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;
}
但它不起作用。如何将缓冲图像转换为相同图像数据的字节数组?
答案 0 :(得分:2)
我不确定术语“二值化”在这种情况下意味着什么。您似乎只想过滤图像(即根据某个阈值切断红色通道)并将结果转换为byte[]
。
假设上述情况正确,请检查以下代码。它会将图像转换为byte[]
以获得32位图像。请考虑以下因素:
byte[]
。您可以在转换期间执行此操作。 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;
}
}
}
}
答案 1 :(得分:2)
为什么不尝试将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);
答案 2 :(得分:1)
怎么样:
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
,它会(可能)抖动图像,但它会使用最少的内存来完成二进制(仅黑/白)的工作。
答案 3 :(得分:1)
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("");
}
}
}