有没有办法在Java中实现“Duotone”效果?
我猜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"));
我的输出
答案 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的产品(按此顺序)并一步完成。