TITLE:ColorConvertOpで画像をグレースケールに変換

Posted by terai at 2005-11-21

ColorConvertOpで画像をグレースケールに変換

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

  • &jnlp;
  • &jar;
  • &zip;

#screenshot

サンプルコード

Image img = icon1.getImage();
BufferedImage source = new BufferedImage(
    img.getWidth(this), img.getHeight(this),
    BufferedImage.TYPE_4BYTE_ABGR);
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);

解説

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

上記のサンプルでは、ラベルをクリックすると元画像とグレースケール画像とが切り替わるようになっています。


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

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

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

class MyGrayFilter extends RGBImageFilter {
  public MyGrayFilter() {
    canFilterIndexColorModel = true;
  }
  public int filterRGB(int x, int y, int rgb) {
    int a = (rgb >> 24) & 0xff;
    int r = (rgb >> 16) & 0xff;
    int g = (rgb >> 8) & 0xff;
    int b = rgb & 0xff;
    //http://ofo.jp/osakana/cgtips/grayscale.phtml
    int m = (2*r+4*g+b)/7; //NTSC係数による加重平均法(近似)
    //return new Color(m,m,m,a).getRGB();
    return (rgb & 0xff000000) | (m<<16) | (m<<8) | (m);
  }
}
FilteredImageSource fis = new FilteredImageSource(img.getSource(), new MyGrayFilter());
icon2 = new ImageIcon(createImage(fis));

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

BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
bi.createGraphics().drawImage(img, 0, 0, this);

参考リンク

コメント

  • リンクを参考にしてRGBImageFilterを使うサンプルを修正しました。 -- terai
  • グレイスケールからグレースケールに変更。 -- terai