【问题标题】:How to control the pixel size of the color model of an ErrorDiffusionDescriptor?如何控制 ErrorDiffusionDescriptor 的颜色模型的像素大小?
【发布时间】:2013-03-10 13:16:33
【问题描述】:

我正在尝试将直接颜色模型图像转换为双色调索引图像(每像素 1 位)并将索引图像保存为 BMP。

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 位图:

此图片大小为 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,但结果图像发生了显着变化:

但是,此图像的大小为 21 KiB,与我使用 MS Paint 将示例图像转换为单色位图时的大小差不多。因此,看起来 JAI 的 BMPImageWriter 使用了正确的编码,但如果您仔细查看第二张图像,相邻的像素列相距 8 个像素。事实上,你可以看到第一张图片,只是第一张图片的每一列像素被扩展为 8 列像素。

这是 JAI 中的错误吗?有什么办法可以将这些 8 宽的像素列折叠为单列像素吗?

【问题讨论】:

    标签: java image bmp jai dithering


    【解决方案1】:

    这应该适用于 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");
    

    【讨论】:

    • 嘿,成功了!我刚刚修改它以使用由颜色量化器 op 计算的查找表,瞧。非常感谢!
    猜你喜欢
    • 2022-12-15
    • 2018-03-23
    • 2018-05-27
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多