Javaで画像を色付けするためのコードに取り組んでいます。基本的に私がやりたいことは、GIMP の colorize コマンドに沿ったものです。そのため、BufferedImage と Color があれば、指定された色で Image を色付けできます。誰でもアイデアはありますか?このようなことを行う上での私の現在の最善の推測は、BufferedImage の各ピクセルの RGB 値を取得し、それに Color の RGB 値を何らかの倍率で追加することです。
4 に答える
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 コマンドを使ったことがありません。ただし、各ピクセルの 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);
}
mask ブール値が true の場合、各色をマスクするBufferedImageOpを作成します。
呼び出すのも簡単です。
BufferedImageOp colorizeFilter = createColorizeOp(R1, G1, B1);
BufferedImage targetImage = colorizeFilter.filter(sourceImage, null);
これが探しているものではない場合は、BufferedImageOp を詳しく調べることをお勧めします。
これは、異なる画像に対して複数回計算を行う必要がないため、より効率的です。または、R1、G1、B1 の値が変わらない限り、別の BufferedImages で計算をやり直してください。
これは GIMP の Colorize 関数とまったく同じように機能し、透明度を保持します。Contrast and Brightness、Hue、Sat、Luminosity などもいくつか追加しました - 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に変換しました。
他の誰かが同じことをしたい場合に備えて、このスレッドに投稿してください(これは、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() );
}
}
}