Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何控制ErrorDiffusionDescriptor颜色模型的像素大小?_Java_Image_Bmp_Jai_Dithering - Fatal编程技术网

Java 如何控制ErrorDiffusionDescriptor颜色模型的像素大小?

Java 如何控制ErrorDiffusionDescriptor颜色模型的像素大小?,java,image,bmp,jai,dithering,Java,Image,Bmp,Jai,Dithering,我正在尝试将直接彩色模型图像转换为双色索引图像(每像素1位),并将索引图像保存为BMP 如合同所述: 编码输出的位深度由源图像的位深度确定 从整体上看,其机制是 使用的缩小副本,我首先执行颜色量化以获得颜色查找表,然后执行错误扩散以应用Floyd–Steinberg抖动: PlanarImage surrogateImage = PlanarImage.wrapRenderedImage(image); PlanarImage op = ColorQuantizerDescriptor.cre

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

如合同所述:

编码输出的位深度由源图像的位深度确定

从整体上看,其机制是

使用的缩小副本,我首先执行颜色量化以获得颜色查找表,然后执行错误扩散以应用Floyd–Steinberg抖动:

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千磅

我在某处看到,将颜色模型传递给错误扩散的一种方法是设置JAI.KEY_IMAGE_布局渲染提示:

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,但结果图像会发生显著变化:

然而,这个图像的大小是21kib,大约是我使用MS Paint将样本图像转换为单色位图时的大小。因此,JAI的
BMPImageWriter
似乎使用了正确的编码,但如果仔细观察第二幅图像,相邻的像素列之间相隔八个像素。实际上,您可以看到第一幅图像,只有第一幅图像中的每一列像素被扩展为8列像素


这是JAI的一只虫子吗?我可以做些什么来将这8列宽的像素折叠成单列像素吗?

这应该适用于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和voilá计算的查找表。非常感谢你!