2011-09-23 174 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,并且也依赖于共享库。我认为你不能避免依赖一些外部图像软件。