2013-03-10 66 views
3

我试图将直接彩色模型图像转换为双色调索引图像(每像素1位)并将索引图像另存为BMP。如何控制ErrorDiffusionDescriptor的颜色模型的像素大小?

如上所述在Java Advanced Imaging API Home Page

编码输出的比特深度是由源图像的确定。

从翻看the source code of BMPImageWriter,其机制是返回值ColorModel#getPixelSize()

使用的an image from Wikimedia Commons按比例缩小的副本,我首先执行颜色量化得到一个颜色查找表,然后误差扩散申请弗洛伊德 - 斯坦伯格抖动:

PlanarImage surrogateImage = PlanarImage.wrapRenderedImage(image); 

PlanarImage op = ColorQuantizerDescriptor.create(surrogateImage, ColorQuantizerDescriptor.OCTTREE, 2, null, null, null, null, null); 
LookupTableJAI lut = (LookupTableJAI)op.getProperty("LUT"); 
IndexColorModel cm = new IndexColorModel(1, lut.getByteData()[0].length, lut.getByteData()[0], lut.getByteData()[1], lut.getByteData()[2]); 

op = ErrorDiffusionDescriptor.create(surrogateImage, lut, KernelJAI.ERROR_FILTER_FLOYD_STEINBERG, null); 

image = op.getAsBufferedImage(); 

的问题是,image.getColorModel().getPixelSize()回报8,因此图像被保存为8bpp的位图:

Result of color quantization and error diffusion on the sample image.

此图像的大小是167 KIB。

我看到的地方,通过一个颜色模型误差扩散的一种方式是设置JAI.KEY_IMAGE_LAYOUT呈现提示:

ImageLayout layout = new ImageLayout(); 
layout.setTileWidth(image.getWidth()); 
layout.setTileHeight(image.getHeight()); 
layout.setColorModel(cm); 
layout.setSampleModel(op.getSampleModel()); 
RenderingHints rh = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout); 
op = ErrorDiffusionDescriptor.create(surrogateImage, lut, KernelJAI.ERROR_FILTER_FLOYD_STEINBERG, rh); 

image.getColorModel().getPixelSize()现在返回1,但由此产生的图像显著改变:

Result of color quantization and error diffusion on the sample image passing an ImageLayout.

但是,这个图像的大小是21 KiB,关于当我使用MS Paint将示例图像转换为单色位图时的大小。因此,看起来JAI的​​正在使用正确的编码,但如果仔细观察第二张图像,则相邻的像素列会相隔八个像素。实际上,您可以看到第一个图像,只有第一个图像的每列像素被扩展为8列像素。

这是JAI中的错误吗?我能做些什么来将这8个像素的像素列合并为单列像素?

回答

2

这应该与24 BPP PNG工作:

String filename = "jEEDL.png"; 

    PlanarImage image = PlanarImage.wrapRenderedImage(JAI.create("fileload", filename)); 

    LookupTableJAI lut = new LookupTableJAI(new byte[][] {{(byte)0x00, (byte)0xff}, {(byte)0x00, (byte)0xff}, {(byte)0x00, (byte)0xff}}); 
    ImageLayout layout = new ImageLayout(); 
    byte[] map = new byte[] {(byte)0x00, (byte)0xff}; 
    ColorModel cm = new IndexColorModel(1, 2, map, map, map); 
    layout.setColorModel(cm); 
    SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, 
      image.getWidth(), 
      image.getHeight(), 
      1); 
    layout.setSampleModel(sm); 
    RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout); 
    PlanarImage op = ErrorDiffusionDescriptor.create(image, lut, KernelJAI.ERROR_FILTER_FLOYD_STEINBERG, hints); 

    BufferedImage dst = op.getAsBufferedImage(); 

    JAI.create("filestore", dst, "jEEDL.bmp", "BMP"); 
+0

嘿,成功了!我只是修改它以使用颜色量化器op和voilà计算的查找表。非常感谢! – 2013-03-20 12:46:49

相关问题