2014-01-27 25 views
0

我一直在嘗試用Java編碼PNG圖像格式的一些數據(表示爲字節值數組0〜255)。使用JavaScript中的HTML canvas元素getImageData()方法讀取數據(類似於:http://blog.nihilogic.dk/2008/05/compression-using-canvas-and-png.html)。Java ImageIO PNG編碼不正確?

但是,輸出數據並不總是與輸入相同。一些值似乎與輸入不同。它似乎將編碼工作爲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

恩,我在想你真的不想標記JavaScript。刪除。 –

+0

'y = 0;'似乎是一個錯誤。也許你的意思是'x = 0;'? – Obicere

+0

你是對的,雖然原始代碼是正確的(我發佈時更改了一些var名稱以提高可讀性)。 – user2272952

回答

0

好的,所以我發現問題只發生在大於256x256的圖像上。我做了一些研究,發現了人們在Chrome中遇到的(雖然不同的)問題(包括畫布元素和這個尺寸的圖片)。所以我嘗試使用Firefox,並沒有錯誤!

似乎Chrome瀏覽器的畫布元素遠非完美。

[使用Chrome版本32.0.1700.77]

編輯:此外,設置鉻://標誌 「禁用加速2D畫布」 使得它在Chrome瀏覽器。

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

(高度=(數據長度+寬度-1)/寬度)是否稍微安全一些?然後你確定目標緩衝區足夠大。目前,如果'data.length%width> 0,你會錯過整行,不是嗎?但是,是的,我想看一個簡單的消息編碼的PNG。 – usr2564301