读取uint16到图像java

时间:2015-04-13 20:49:11

标签: java image binary bufferedimage

我有一个.bin文件,它是在MATLAB代码中用uint16创建的,我需要用Java读取它。

使用下面的代码,我得到一个模糊的图像,灰度很差,文件的长度似乎是像素数量的两倍。以这种方式读取文件时似乎有一些信息丢失。有没有办法读取输入流以外的.bin文件?

这是我尝试阅读.bin文件的方式:

is = new FileInputStream(filename);
dis = new DataInputStream(is);

int[] buf = new int[length];
int[][] real = new int[x][y];

while (dis.available() > 0) {
    buf[i] = dis.readShort();
}
int counter = 0;
for (int j = 0; j < x; j++) {
    for (int k = 0; k < y; k++) {
        real[j][k] = buf[counter];
        counter++;
    }
}
return real;

这是来自调用第一个类的主类的部分:

BinaryFile2 binary = new BinaryFile2();
int[][] image = binary.read("data001.bin", 1024, 2048);         
BufferedImage theImage = new BufferedImage(1024, 2048,
        BufferedImage.TYPE_BYTE_GRAY);
for (int y = 0; y < 2048; y++) {
    for (int x = 0; x < 1024; x++) {
        int value = image[x][y];
        theImage.setRGB(x, y, value);
    }
}
File outputfile = new File("saved.png");
ImageIO.write(theImage, "png", outputfile);

2 个答案:

答案 0 :(得分:0)

您将uint16数据存储在int数组中,这可能会导致数据丢失/损坏。

以下帖子讨论了类似的问题:

Java read unsigned int, store, and write it back

答案 1 :(得分:0)

要正确阅读并显示最初存储为uint16的图片,最好使用BufferedImage.TYPE_USHORT_GRAY类型。 Java short为16位,DataBufferUShort用于存储无符号16位值。

试试这个:

InputStream is = ...;
DataInputStream data = new DataInputStream(is);

BufferedImage theImage = new BufferedImage(1024, 2048, BufferedImage.TYPE_USHORT_GRAY);

short[] pixels = ((DataBufferUShort) theImage.getRaster().getDataBuffer()).getData();

for (int i = 0; i < pixels.length; i++) {
    pixels[i] = data.readShort(); // short value is signed, but DataBufferUShort will take care of the "unsigning"
}

// TODO: close() streams in a finally block

要将图像进一步转换为8位图像,您可以创建一个新图像并将原始图像绘制到该图像上:

BufferedImage otherImage = new BufferedImage(1024, 2048, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g = otherImage.createGraphics();
try {
    g.drawImage(theImage, 0, 0, null);
}
finally {
   g.dispose();
}

现在您可以将otherImage存储为八位灰度PNG。