首页 / 知识

关于颜色:用Java着色图像

2023-04-12 23:32:00

关于颜色:用Java着色图像

Colorizing images in Java

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


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

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

如果(R1,G1,B1)是您要使用的颜色。


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

使用上面的Nicks示例来说明我该怎么做。

Let Y = 0.3*R + 0.59*G + 0.11*B for
each pixel

(R1,G1,B1) is what you are colorizing
with

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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,它将屏蔽每种颜色。

调用也很简单。

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

如果这不是您要寻找的内容,建议您进一步研究BufferedImageOp \\。

这也将更加高效,因为您无需对不同的图像进行多次计算。或者只要不改变R1,G1,B1的值,就在不同的BufferedImages上再次进行计算。


这与GIMP中的Colorize函数完全一样,并且保留了透明度。我还添加了一些东西,例如"对比度和亮度","色相","饱和度"和"亮度"-0circle0 Google Me-> \\'Sprite Creator 3 \\'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
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。

将其发布到此线程中,以防万一其他人想要这样做(因为这是Google中出现的第一个线程)。转换仍会在不应该更改的情况下更改白色,这可能是从双精度转换为整数的强制转换问题。该类将就地转换BufferedImage。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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() );

      }
   }
}

图像命令缩放像素

最新内容

相关内容

热门文章

推荐文章

标签云

猜你喜欢