Java ImageIO PNG编码错误?

时间:2014-01-27 02:45:21

标签: java png javax.imageio

我一直在尝试使用Java以PNG图像格式编码一些数据(表示为字节值0-255的数组)。使用JavaScript中的HTML canvas元素getImageData()方法读取数据(类似于:http://blog.nihilogic.dk/2008/05/compression-using-canvas-and-png.html)。

但是,输出数据并不总是与输入相同。某些值似乎与输入不同。它似乎将编码工作为1像素高的图像,并且仅对具有多行的图像不正确。我有一个想法,它可能是由PNG图像的逐行过滤引起的,但实际上并不知道。

似乎每个不正确的值只有1或2错误。

这是Java代码,但我想知道它是否也是ImageIO api的一个问题,特别是它的PNG编码器?

public static File encodeInPng(byte[] data, String filename) throws java.io.IOException{
    int width = (int)Math.ceil(Math.sqrt(data.length));
    int height = (int)Math.ceil((double)data.length/width);

    BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);

    int x = 0, y = 0;
    for (byte b : data) {
        bufImg.getRaster().setPixel(x, y, new int[]{b&0xFF});
        x++;
        if (x == width) {
            x = 0;
            y ++;
        }
    }

    File f = new File(filename);
    ImageIO.write(bufImg, "png", f);

    return f;
}

编辑:只有特定大小的PNG文件出现问题(大约50 kB,或者​​可能是256x256px)。

2 个答案:

答案 0 :(得分:0)

尺寸的计算相当丑陋,代码的某些部分可能稍微高效和干净 - 一些抛光在下面。但是你的代码看起来基本上是正确的,它对我有用。你能传递一个“输出数据与输入不同”的例子吗?

public static File encodeInPng(byte[] data, String filename) 
         throws java.io.IOException {
    int width = (int) Math.ceil(Math.sqrt(data.length));
    int height = data.length / width;
    BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
    int[] pix = new int[1];
    int pos = 0;
    for( int y = 0; y < height; y++ ) {
        for( int x = 0; x < width; x++ ) {
            pix[0] = data[pos++] & 0xFF;
            bufImg.getRaster().setPixel(x, y, pix);
        }
    }
    File f = new File(filename);
    ImageIO.write(bufImg, "png", f);
    return f;
}

答案 1 :(得分:0)

好的,所以我发现问题只发生在大于256x256的图像上。我做了一些研究,发现了人们在Chrome中遇到的现有(虽然不同)问题(使用canvas元素和这个尺寸的图像)。所以我尝试使用Firefox,没有错误!

似乎Chrome画布元素远非完美。

[使用Chrome版本32.0.1700.77]

修改:此外,设置chrome:// flags“禁用加速的2D画布”使其在Chrome中运行。