• category: swing folder: ColorConvertOp title: ColorConvertOpで画像をグレースケールに変換 tags: [ColorConvertOp, BufferedImage, RGBImageFilter, ImageIcon] author: aterai pubdate: 2005-11-21T14:18:04+09:00 description: ColorConvertOpを使って画像をグレースケールに変換します。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTJmEhFayI/AAAAAAAAAUo/x4JGGk_f08c/s800/ColorConvertOp.png

概要

ColorConvertOpを使って画像をグレースケールに変換します。

サンプルコード

Image img = icon1.getImage();
BufferedImage source = new BufferedImage(
    img.getWidth(this), img.getHeight(this), BufferedImage.TYPE_INT_ARGB);
Graphics g = source.createGraphics();
g.drawImage(img, 0, 0, this);
g.dispose();

ColorConvertOp colorConvert = new ColorConvertOp(
    ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
BufferedImage destination = colorConvert.filter(source, null);
icon2 = new ImageIcon(destination);
View in GitHub: Java, Kotlin

解説

用意したアイコンから、BufferedImageを作成し、これをColorConvertOp#filterメソッドを使ってグレースケールに変換しています。

上記のサンプルでは、各JLabelをクリックでIconとして表示されている元画像とグレースケール画像を切り替えています。


以下のようにGrayFilter.createDisabledImage(...)を使った場合よりきれいに変換できるようです。

icon2 = new ImageIcon(GrayFilter.createDisabledImage(img));

GrayFilterの代わりに、以下のようなRGBImageFilterを継承したフィルタを使う方法もあります。

class MyGrayFilter extends RGBImageFilter {
  public int filterRGB(int x, int y, int argb) {
    //int a = (argb >> 24) & 0xFF;
    int r = (argb >> 16) & 0xFF;
    int g = (argb >>  8) & 0xFF;
    int b = (argb      ) & 0xFF;
    //http://ofo.jp/osakana/cgtips/grayscale.phtml
    int m = (2 * r + 4 * g + b) / 7; //NTSC Coefficients
    return (argb & 0xFF_00_00_00) | (m << 16) | (m << 8) | m;
  }
}
// ...
ImageProducer ip = new FilteredImageSource(img.getSource(), new MyGrayFilter());
icon2 = new ImageIcon(Toolkit.getDefaultToolkit().createImage(ip));

BufferedImage.TYPE_BYTE_GRAYで、BufferedImageを作成して複写してもグレースケールに変換できますが、透過色を使用している場合はすこし注意が必要なようです(参考: Swing - Color to Grayscale to Binary)。

BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
Graphics g = bi.createGraphics();
//g.setColor(Color.WHITE);
g.fillRect(0, 0, w, h); // pre-fill: alpha
g.drawImage(img, 0, 0, this);
g.dispose();

参考リンク

コメント