java colors bufferedimage colorize

Colorear imágenes en Java



colors bufferedimage (4)

Estoy trabajando en algún código para colorear una imagen en Java. Básicamente, lo que me gustaría hacer es algo similar a la orden de coloreado de GIMP, de modo que si tengo una Imagen Buffered y un Color, puedo colorear la Imagen con el color dado. ¿Alguien tiene alguna idea? Mi mejor conjetura actual para hacer algo como esto es obtener el valor rgb de cada píxel en la Imagen Buffered y agregarle el valor RGB del Color con algún factor de escala.


Deje Y = 0.3*R + 0.59*G + 0.11*B para cada píxel en la imagen, luego configúrelos para que sean

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

si (R1,G1,B1) es con lo que te coloreas.


Nunca he usado el comando colorize de GIMP. Sin embargo, si obtiene el valor RGB de cada píxel y le agrega valor RGB, realmente debería usar un LookupOp . Aquí hay un código que escribí para aplicar BufferedImageOp a una Imagen Buffered.

Usando el ejemplo de Nicks de arriba aquí cómo lo haría.

Deje Y = 0.3 * R + 0.59 * G + 0.11 * B por cada píxel

(R1, G1, B1) es con lo que estás coloreando

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); }

Crea un BufferedImageOp que enmascara cada color si la máscara booleana es verdadera.

Es fácil de llamar también.

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

Si esto no es lo que estás buscando, te sugiero que busques más en BufferedImageOp.

Esto también sería más eficiente ya que no necesitaría hacer los cálculos varias veces en diferentes imágenes. O haga los cálculos otra vez en diferentes imágenes almacenadas siempre que los valores R1, G1, B1 no cambien.


Esto funciona exactamente como la función Colorear en GIMP y conserva la transparencia. También agregué algunas cosas como Contraste y Brillo, Tono, Sat y Luminosidad - 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; } }


Quería hacer exactamente lo mismo que quería hacer el póster de la pregunta, pero la conversión anterior no eliminó los colores como lo hace el GIMP (es decir, verde con una superposición roja con un color marrón desagradable, etc.). Así que descargué el código fuente de GIMP y convertí el código c en Java.

Publicarlo en este hilo por si acaso alguien más quiere hacer lo mismo (ya que es el primer hilo que aparece en Google). La conversión aún cambia el color blanco cuando no debería, probablemente sea un problema de conversión de doble a int. La clase convierte una Imagen Buffered en el lugar.

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() ); } } }