2008-08-22 61 views
4

我正在研究一些代碼以使用Java着色圖像。基本上我想要做的是沿着GIMP的colorize命令行,所以如果我有一個BufferedImage和一個Color,我可以使用給定的顏色對Image進行着色。任何人有任何想法?我現在最好的做法是獲取BufferedImage中每個像素的RGB值,並將Color的RGB值與一些縮放因子相加。在Java中着色圖像

回答

3

我從來沒有使用過GIMP的colorize命令。但是,如果您獲取每個像素的RGB值並向其添加RGB值,則應該使用LookupOp下面是我寫的一個代碼,用於將BufferedImageOp應用於BufferedImage。

使用從上面的尼克斯例子繼承人如何做到這一點。

設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布爾值爲true,它將遮蓋每種顏色。

它也很簡單。

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

如果這不是你想要的,我建議你看看更多BufferedImageOp的。

這樣做也會更有效率,因爲您不需要在不同的圖像上多次執行計算。或者只要R1,G1,B1的值不變,就可以在不同的BufferedImages上再次進行計算。

+0

將這個正確recolorize圖片與我們選擇的隨機顏色? – 2015-03-19 17:17:39

7

Y = 0.3*R + 0.59*G + 0.11*B對圖像中的每個像素,然後將它們設置爲

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

如果(R1,G1,B1)是你與着色。

1

我想做與問題海報想要做的完全相同的事情,但上面的轉換並沒有像GIMP那樣去除顏色(即帶有紅色覆蓋層的綠色使得令人不愉快的棕色等)。所以我下載了GIMP的源代碼並將c代碼轉換爲Java。

將其發佈到該主題中,以防萬一其他人想要做同樣的事情(因爲它是Google中的第一個線程)。當它不應該轉換時,轉換仍會改變白色,這可能是從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()); 

     } 
    } 
} 
2

這與GIMP中的Colorize函數完全相同,它保留了透明度。我還添加了像對比度和亮度,色調,飽和,和光度的幾件事 - 0circle0谷歌我 - >「雪碧造物主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; 
    } 
} 
+0

這正是我所期待的。通過使用GIMP與輸入值一起玩,直到獲得所需的顏色,它使得黑色PNG圖標着色非常容易。 – bspkrs 2016-03-23 22:24:09