2011-09-23 178 views
3

我有一堆圖像,對許多手工做的是16色8位PNG格式,我需要16位4位格式,它們都具有相同的調色板。使用Java或Python將8位(16調色板)PNG轉換爲4位(16色調色板)?

我正在淘谷歌的最佳圖書館使用,但我沒有找到很多關於這個具體問題,所以我來這裏希望一些更有針對性的解決方案。

我想使用基於other answers I have found here的PIL,但沒有任何運氣。

img = Image.open('DownArrow_focused.png') 
img = img.point(lambda i: i * 16, "L") 
img.save('DownArrow_focused.png', 'PNG') 

但這給了我一個灰度圖像,而不是我想要的。

PIL將無法正常工作,嘗試PyPNG。 GIMP做到了這一點,但是我有成百上千的這些東西需要批量處理。並獲得批量的這些轉換,所以這不是一次性的事情。

基於Java的解決方案也是可以接受的,幾乎所有可以在Linux/OSX機器上從命令行運行的東西都是可以接受的。

+0

據我所見,PIL沒有[4位模式](http://www.pythonware.com/library/pil/handbook/concepts.htm),所以你需要另一種方法。 – Voo

+0

我很好奇你爲什麼認爲你需要這個。它已經有16種顏色,所以在強制PNG壓縮之後,它的大小不會有任何不同。 –

+0

@Mark是因爲我的硬件只能讀取真正的4位PNG,這就是爲什麼,而且它們的確會變得更小,這在這種情況下與我相關,但這不是我需要這樣做的原因的根源。 –

回答

1

在PNG中,調色板始終以RGB8(每個索引= 3個字節=顏色)存儲,並具有任意(最多256個)條目數。如果當前有16位調色板的8位圖像(總共16個條目),則不需要更改調色板,只需重新包裝像素字節(每個字節有兩個索引)。如果是這樣,我想你可以用PNGJ與此代碼(未經測試)做到這一點:

public static void reencode(String orig, String dest) { 
    PngReader png1 = FileHelper.createPngReader(new File(orig)); 
    ImageInfo pnginfo1 = png1.imgInfo; 
    ImageInfo pnginfo2 = new ImageInfo(pnginfo1.cols, pnginfo1.rows, 4, false,false,true); 
    PngWriter png2 = FileHelper.createPngWriter(new File(dest), pnginfo2, false); 
    png2.copyChunksFirst(png1, ChunksToWrite.COPY_ALL); 
    ImageLine l2 = new ImageLine(pnginfo2); 
    for (int row = 0; row < pnginfo1.rows; row++) { 
     ImageLine l1 = png1.readRow(row); 
     l2.tf_pack(l1.scanline, false); 
     l2.setRown(row); 
     png2.writeRow(l2); 
    } 
    png1.end(); 
    png2.copyChunksLast(png1, ChunksToWrite.COPY_ALL); 
    png2.end(); 
    System.out.println("Done"); 
} 

在其他地方,如果您當前的調色板中有16個「拿來主義」的色彩(但其長度更大,因爲它包含未使用的顏色),你需要做一些工作,修改調色板塊(但也可以完成)。

+0

圖像是16種索引顏色,但8位,因爲這是所有的Photoshop可以保存爲。你是正確的,我需要做的就是減少像素字節。 –

+0

@JarrodRoberson:那麼上面的代碼應該可以工作。 – leonbloy

0

呼叫的NetPBM程序 http://netpbm.sourceforge.net/ 使用以下命令的Python腳本:

$ pngtopnm test.png | pnmquant 16 | pnmtopng > test16.png 

$ file test16.png 
test16.png: PNG image data, 700 x 303, 4-bit colormap, non-interlaced 

而且GIMP報告test16.png具有Color space: Indexed color (16 colors), 我的猜測是你想要的。

這不是一個純粹的Python解決方案,但PIL也不是純粹的Python,並且也依賴於共享庫。我認爲你不能避免依賴一些外部圖像軟件。