如何在Java中实现“Duotone”效果

时间:2012-08-03 09:29:41

标签: java image-processing

有没有办法在Java中实现“Duotone”效果?

我想做的一个很好的例子是herehere

我猜BandCombineOp可能有所帮助。 对我来说,我应该首先将其转换为灰色,然后应用像阈值效果一样的smth。 但我没有达到良好的产出。

另外,我不明白如何为此效果设置颜色。

float[][] grayMatrix = new float[][]
            {
               new float[] {0.3f, 0.3f, 0.3f},
               new float[] {0.3f, 0.3f, 0.3f},
               new float[] {0.3f, 0.3f, 0.3f},
            };

    float[][] duoToneMatrix = new float[][]
            {
                    new float[] {0.1f, 0.1f, 0.1f},
                    new float[] {0.2f, 0.2f, 0.2f},
                    new float[] {0.1f, 0.1f, 0.1f},
            };

    BufferedImage src = ImageIO.read(new File("X:\\photoshop_image_effects.jpg"));
    WritableRaster srcRaster = src.getRaster();

    // make it gray
    BandCombineOp bco = new BandCombineOp(grayMatrix, null);
    WritableRaster dstRaster = bco.createCompatibleDestRaster(srcRaster);
    bco.filter(srcRaster, dstRaster);

    // apply duotone
    BandCombineOp duoToneBco = new BandCombineOp(duoToneMatrix, null);
    WritableRaster dstRaster2 = bco.createCompatibleDestRaster(dstRaster);
    duoToneBco.filter(dstRaster, dstRaster2);

    BufferedImage result = new BufferedImage(src.getColorModel(), dstRaster2, src.getColorModel().isAlphaPremultiplied(), null);
    ImageIO.write(result, "png", new File("X:\\result_duotone.png"));

我的输出enter image description here

1 个答案:

答案 0 :(得分:2)

据我所知,你试图改变图像的颜色而不改变它的luminosity。注意与亮度的区别。

无论您的目标是亮度还是亮度,您的问题都归结为改变B,G和R的相对贡献而不改变它们的加权和。您的第一个矩阵通过将B,G,R设置为相同的值并仅稍微改变其亮度(.3 + .3 + .3 = .9)来转换为灰度。要使用亮度,请使用

greyMatrix = (.11,.59,.3,
              .11,.59,.3,
              .11,.59,.3); //note this is for bgr

然后你想改变他们的相对权重而不改变他们的加权和。首先,请注意,由于灰度转换后您的B,G,R值相同,您可以用

替换矩阵
duoToneMatrix = (0,.3,0,
                 0,.6,0,
                 0,.3,0,)

它将是等效的。为了节省亮度,您需要选择3个因子,使得它们的总和为1.这三个因子可以应用于duoTone矩阵。因子越大,图像与该颜色的着色越多。为了保持光度,你需要3个因子fb,fg,fr

fb*.11+fg*.59+fr*.3 = 1; //again for bgr

您可以选择因子fb,fg,fr来找到您选择的色调。

另请注意,您可以使用一个矩阵执行此操作。只需合并你已经拥有的两个矩阵。

[duoToneMatrix]*[greyMatrix]*vector = ([duoToneMatrix]*[greyMatrix])*vector;

只需计算duoToneMatrix和greyMatrix的产品(按此顺序)并一步完成。