给定一张白色和黑色的图像,没有灰色(在 ARGB 中:
0xFFFFFFFF
和 0xFF000000
),我想将黑色着色为特定颜色,将白色着色为另一种特定颜色。
为此,我目前使用以下代码:
private LookupOp createLookupOp(Color foreground, Color background) {
var lookupTable = new byte[4][256];
var fg = foreground.getRGB();
Arrays.fill(lookupTable[0], (byte) (fg >> 16));
Arrays.fill(lookupTable[1], (byte) (fg >> 8));
Arrays.fill(lookupTable[2], (byte) (fg));
Arrays.fill(lookupTable[3], (byte) (fg >> 24));
var bg = background.getRGB();
lookupTable[0][0] = (byte) (bg >> 16);
lookupTable[1][0] = (byte) (bg >> 8);
lookupTable[2][0] = (byte) (bg);
lookupTable[3][0] = (byte) (bg >> 24);
return new LookupOp(new ByteLookupTable(0, lookupTable), null);
}
然后我可以这样使用它:
var lookup = lookups.computeIfAbsent(colorPair, colors -> createLookupOp(colors.foreground, colors.background));
var coloredImage = lookup.filter(originalImage, null);
graphics2d.drawImage(coloredImage, originalWidth, originalHeight, null);
它完成了工作。但我质疑这个过程,因为它使用大量内存(每个颜色对至少 1kb),而且当我有数千张需要用不同颜色绘制的迷你图像时,创建速度相当慢。
为了加快速度,我将结果存储在地图中,但即便如此,在应用程序运行结束时我的地图中仍然有大约 200,000 个项目,大约 200 MB 存储在我的地图中。
我想知道是否有便宜又快速的替代品
LookupOp
.
这是我在评论中概述的想法的更详细版本,假设黑白图像是带有
IndexColorModel
的 1 位图像(如果不是,当然可以转换)。鉴于此,我们可以交换调色板或IndexColorModel
,让图像立即重新着色。
代码看起来像这样:
// The original B/W image
IndexColorModel blackAndWhite = new IndexColorModel(1, 2, new int[] {0x000000, 0xFFFFFF}, 0, false, -1, DataBuffer.TYPE_BYTE);
BufferedImage bwImage = new BufferedImage(10, 10, BufferedImage.TYPE_BYTE_BINARY, blackAndWhite);
// A new color pair
Color red = Color.RED;
Color blue = Color.BLUE;
// Create a palette from the color pair
IndexColorModel redAndBlue = new IndexColorModel(1, 2, new int[] {red.getRGB(), blue.getRGB()}, 0, false, -1, DataBuffer.TYPE_BYTE);
// And finally a new two-colored image from the original image, using the new palette
BufferedImage rbImage = new BufferedImage(redAndBlue, bwImage.getRaster(), reaAndBlue.isAlphaPremultiplied(), null);
现在,两张图片共享光栅,所以改变一张也会改变另一张。这在内存和 CPU 方面非常便宜。但是,如果不需要,您可以在最后一行将
bwImage.getRaster()
替换为 bwImage.copyData(null)
,以创建“分离”副本。
您还可以为每对颜色缓存
IndexColorModel
s,就像您对上面的LookupOp
s 所做的那样,但我不确定这是否值得(取决于您重复使用颜色对的频率)。