【问题标题】:Colorizing images in Java在 Java 中为图像着色
【发布时间】:2008-08-22 23:57:13
【问题描述】:

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

【问题讨论】:

    标签: java colors bufferedimage colorize


    【解决方案1】:

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

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

    如果 (R1,G1,B1) 是您正在着色的对象。

    【讨论】:

      【解决方案2】:

      我从未使用过 GIMP 的 colorize 命令。但是,如果您获取每个像素的 RGB 值并向其添加 RGB 值,您应该真正使用 LookupOp这是我编写的一些代码,用于将 BufferedImageOp 应用于 BufferedImage。 p>

      使用上面的 Nicks 示例说明我将如何做。

      让 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,如果掩码布尔值为真,它将屏蔽每种颜色。

      调用也很简单。

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

      如果这不是您想要的,我建议您更多地研究 BufferedImageOp。

      这也会更有效,因为您不需要对不同的图像进行多次计算。或者,只要 R1、G1、B1 值不变,就对不同的 BufferedImage 重新计算。

      【讨论】:

      • 这会用我们选择的随机颜色正确地重新着色图片吗?
      【解决方案3】:

      这与 GIMP 中的着色功能完全一样,它保留了透明度。我还添加了一些东西,例如对比度和亮度、色相、饱和度和亮度 - 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 处理输入值直到获得所需的颜色,这使得为黑色 png 图标着色变得非常容易。
      • 唯一的区别是亮度/亮度与 GIMP 的“着色”对话框中的滑块不太一样,但总的来说它可以满足我的需要。
      【解决方案4】:

      我想做与问题发布者想做的完全相同的事情,但上面的转换并没有像 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() );
      
            }
         }
      }
      

      【讨论】:

        猜你喜欢
        • 2023-02-22
        • 2011-12-18
        • 1970-01-01
        • 2014-02-18
        • 2018-09-05
        • 1970-01-01
        • 1970-01-01
        • 2016-07-04
        • 2012-01-17
        相关资源
        最近更新 更多