用Java着色图像

我正在研究一些代码来用Java着色图像。 基本上我想要做的是GIMP的colorize命令,所以如果我有一个BufferedImage和Color,我可以用给定的颜色着色Image。 有人有任何想法吗? 我目前做这样的事情的最佳猜测是获取BufferedImage中每个像素的rgb值,并使用一些缩放因子将Color的RGB值添加到其中。

我从未使用过GIMP的colorize命令。 但是,如果你获得每个像素的RGB值并向其添加RGB值,你应该使用LookupOp 。 下面是我编写的一些代码,用于将BufferedImageOp应用于BufferedImage。

使用上面的尼克斯示例inheritance人我将如何做到这一点。

对于每个像素,设Y = 0.3 * R + 0.59 * G + 0.11 * B.

(R1,G1,B1)是你着色的

protected LookupOp createColorizeOp(short R1, short G1, short B1) { short[] alpha = new short[256]; short[] red = new short[256]; short[] green = new short[256]; short[] blue = new short[256]; int Y = 0.3*R + 0.59*G + 0.11*B for (short i = 0; i < 256; i++) { alpha[i] = i; red[i] = (R1 + i*.3)/2; green[i] = (G1 + i*.59)/2; blue[i] = (B1 + i*.11)/2; } short[][] data = new short[][] { red, green, blue, alpha }; LookupTable lookupTable = new ShortLookupTable(0, data); return new LookupOp(lookupTable, null); } 

它创建了一个BufferedImageOp ,如果mask boolean为true,它将屏蔽掉每种颜色。

它也很简单。

 BufferedImageOp colorizeFilter = createColorizeOp(R1, G1, B1); BufferedImage targetImage = colorizeFilter.filter(sourceImage, null); 

如果这不是你想要的,我建议你多看看BufferedImageOp。

这也会更有效,因为您不需要在不同的图像上多次进行计算。 或者,只要R1,G1,B1值不变,就可以在不同的BufferedImages上再次进行计算。

对图像中的每个像素设Y = 0.3*R + 0.59*G + 0.11*B ,然后将它们设置为

((R1+Y)/2,(G1+Y)/2,(B1+Y)/2)

if (R1,G1,B1)是你着色的地方。

这与GIMP中的Colorize函数完全相同,它保留了透明度。 我还添加了一些像对比度和亮度,色相,星期六和亮度的东西 – 0circle0 Google Me – >’Sprite Creator 3′

 import java.awt.Color; import java.awt.image.BufferedImage; public class Colorizer { public static final int MAX_COLOR = 256; public static final float LUMINANCE_RED = 0.2126f; public static final float LUMINANCE_GREEN = 0.7152f; public static final float LUMINANCE_BLUE = 0.0722f; double hue = 180; double saturation = 50; double lightness = 0; int[] lum_red_lookup; int[] lum_green_lookup; int[] lum_blue_lookup; int[] final_red_lookup; int[] final_green_lookup; int[] final_blue_lookup; public Colorizer() { doInit(); } public void doHSB(double t_hue, double t_sat, double t_bri, BufferedImage image) { hue = t_hue; saturation = t_sat; lightness = t_bri; doInit(); doColorize(image); } private void doInit() { lum_red_lookup = new int[MAX_COLOR]; lum_green_lookup = new int[MAX_COLOR]; lum_blue_lookup = new int[MAX_COLOR]; double temp_hue = hue / 360f; double temp_sat = saturation / 100f; final_red_lookup = new int[MAX_COLOR]; final_green_lookup = new int[MAX_COLOR]; final_blue_lookup = new int[MAX_COLOR]; for (int i = 0; i < MAX_COLOR; ++i) { lum_red_lookup[i] = (int) (i * LUMINANCE_RED); lum_green_lookup[i] = (int) (i * LUMINANCE_GREEN); lum_blue_lookup[i] = (int) (i * LUMINANCE_BLUE); double temp_light = (double) i / 255f; Color color = new Color(Color.HSBtoRGB((float) temp_hue, (float) temp_sat, (float) temp_light)); final_red_lookup[i] = (int) (color.getRed()); final_green_lookup[i] = (int) (color.getGreen()); final_blue_lookup[i] = (int) (color.getBlue()); } } public void doColorize(BufferedImage image) { int height = image.getHeight(); int width; while (height-- != 0) { width = image.getWidth(); while (width-- != 0) { Color color = new Color(image.getRGB(width, height), true); int lum = lum_red_lookup[color.getRed()] + lum_green_lookup[color.getGreen()] + lum_blue_lookup[color.getBlue()]; if (lightness > 0) { lum = (int) ((double) lum * (100f - lightness) / 100f); lum += 255f - (100f - lightness) * 255f / 100f; } else if (lightness < 0) { lum = (int) (((double) lum * (lightness + 100f)) / 100f); } Color final_color = new Color(final_red_lookup[lum], final_green_lookup[lum], final_blue_lookup[lum], color.getAlpha()); image.setRGB(width, height, final_color.getRGB()); } } } public BufferedImage changeContrast(BufferedImage inImage, float increasingFactor) { int w = inImage.getWidth(); int h = inImage.getHeight(); BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { Color color = new Color(inImage.getRGB(i, j), true); int r, g, b, a; float fr, fg, fb; r = color.getRed(); fr = (r - 128) * increasingFactor + 128; r = (int) fr; r = keep256(r); g = color.getGreen(); fg = (g - 128) * increasingFactor + 128; g = (int) fg; g = keep256(g); b = color.getBlue(); fb = (b - 128) * increasingFactor + 128; b = (int) fb; b = keep256(b); a = color.getAlpha(); outImage.setRGB(i, j, new Color(r, g, b, a).getRGB()); } } return outImage; } public BufferedImage changeGreen(BufferedImage inImage, int increasingFactor) { int w = inImage.getWidth(); int h = inImage.getHeight(); BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { Color color = new Color(inImage.getRGB(i, j), true); int r, g, b, a; r = color.getRed(); g = keep256(color.getGreen() + increasingFactor); b = color.getBlue(); a = color.getAlpha(); outImage.setRGB(i, j, new Color(r, g, b, a).getRGB()); } } return outImage; } public BufferedImage changeBlue(BufferedImage inImage, int increasingFactor) { int w = inImage.getWidth(); int h = inImage.getHeight(); BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { Color color = new Color(inImage.getRGB(i, j), true); int r, g, b, a; r = color.getRed(); g = color.getGreen(); b = keep256(color.getBlue() + increasingFactor); a = color.getAlpha(); outImage.setRGB(i, j, new Color(r, g, b, a).getRGB()); } } return outImage; } public BufferedImage changeRed(BufferedImage inImage, int increasingFactor) { int w = inImage.getWidth(); int h = inImage.getHeight(); BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { Color color = new Color(inImage.getRGB(i, j), true); int r, g, b, a; r = keep256(color.getRed() + increasingFactor); g = color.getGreen(); b = color.getBlue(); a = color.getAlpha(); outImage.setRGB(i, j, new Color(r, g, b, a).getRGB()); } } return outImage; } public BufferedImage changeBrightness(BufferedImage inImage, int increasingFactor) { int w = inImage.getWidth(); int h = inImage.getHeight(); BufferedImage outImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { Color color = new Color(inImage.getRGB(i, j), true); int r, g, b, a; r = keep256(color.getRed() + increasingFactor); g = keep256(color.getGreen() + increasingFactor); b = keep256(color.getBlue() + increasingFactor); a = color.getAlpha(); outImage.setRGB(i, j, new Color(r, g, b, a).getRGB()); } } return outImage; } public int keep256(int i) { if (i <= 255 && i >= 0) return i; if (i > 255) return 255; return 0; } } 

我想做与问题海报想要做的完全相同的事情但是上面的转换并没有像GIMP那样去除颜色(即带有红色覆盖的绿色会产生令人不快的棕色等)。 所以我下载了GIMP的源代码并将c代码转换为Java。

在这个post中发布它以防万一其他人想要做同样的事情(因为它是谷歌中出现的第一个线程)。 当它不应该转换时仍会改变白色,这可能是从double到int的转换问题。 该类就地转换BufferedImage。

 public class Colorize { public static final int MAX_COLOR = 256; public static final float LUMINANCE_RED = 0.2126f; public static final float LUMINANCE_GREEN = 0.7152f; public static final float LUMINANCE_BLUE = 0.0722f; double hue = 180; double saturation = 50; double lightness = 0; int [] lum_red_lookup; int [] lum_green_lookup; int [] lum_blue_lookup; int [] final_red_lookup; int [] final_green_lookup; int [] final_blue_lookup; public Colorize( int red, int green, int blue ) { doInit(); } public Colorize( double t_hue, double t_sat, double t_bri ) { hue = t_hue; saturation = t_sat; lightness = t_bri; doInit(); } public Colorize( double t_hue, double t_sat ) { hue = t_hue; saturation = t_sat; doInit(); } public Colorize( double t_hue ) { hue = t_hue; doInit(); } public Colorize() { doInit(); } private void doInit() { lum_red_lookup = new int [MAX_COLOR]; lum_green_lookup = new int [MAX_COLOR]; lum_blue_lookup = new int [MAX_COLOR]; double temp_hue = hue / 360f; double temp_sat = saturation / 100f; final_red_lookup = new int [MAX_COLOR]; final_green_lookup = new int [MAX_COLOR]; final_blue_lookup = new int [MAX_COLOR]; for( int i = 0; i < MAX_COLOR; ++i ) { lum_red_lookup [i] = ( int )( i * LUMINANCE_RED ); lum_green_lookup[i] = ( int )( i * LUMINANCE_GREEN ); lum_blue_lookup [i] = ( int )( i * LUMINANCE_BLUE ); double temp_light = (double)i / 255f; Color color = new Color( Color.HSBtoRGB( (float)temp_hue, (float)temp_sat, (float)temp_light ) ); final_red_lookup [i] = ( int )( color.getRed() ); final_green_lookup[i] = ( int )( color.getGreen() ); final_blue_lookup [i] = ( int )( color.getBlue() ); } } public void doColorize( BufferedImage image ) { int height = image.getHeight(); int width; while( height-- != 0 ) { width = image.getWidth(); while( width-- != 0 ) { Color color = new Color( image.getRGB( width, height ) ); int lum = lum_red_lookup [color.getRed ()] + lum_green_lookup[color.getGreen()] + lum_blue_lookup [color.getBlue ()]; if( lightness > 0 ) { lum = (int)((double)lum * (100f - lightness) / 100f); lum += 255f - (100f - lightness) * 255f / 100f; } else if( lightness < 0 ) { lum = (int)(((double)lum * lightness + 100f) / 100f); } Color final_color = new Color( final_red_lookup[lum], final_green_lookup[lum], final_blue_lookup[lum], color.getAlpha() ); image.setRGB( width, height, final_color.getRGB() ); } } }