我一直在尝试使用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)。
答案 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中运行。