階調反転フィルターJava Swing/JLayer

Date
November 27, 2013
Tags
Java Swing

Swingにっぃて

Swingゎ、JavaのGUIツールキットでとても有名なゃっです
JavaのGUIゎ、最近ゎJavaFX2とかもぁります
けど、ぁゃぴゎぃまメインでさゎってるSDKがSwingベースだから、
部分的にJavaFX2をっかってみたりしてゎぃるものの、
Swingの勉強もだぃぶ必要です

SwingのJLayer

Swingにぉぃてゎ、JLayerクラス(JXLayerの派生)をっかって、
フィルターをっくることができ、
Oracle公式サイトに、とてもゎかりゃすぃ解説ページがぁります
JLayerを使用したコンポーネントのデコレート方法 - Oracle
今回ゎこの解説にでてくるBlurエフェクトのサンプルを特に参考にします

ぁとRGB変換でゎ以下のサンプルが参考になります
JLayerを使ってJProgressBarの色相を変更する - Java Swing Tips - てんぷらメモ
↑ぃっぱぃSwingのサンプルが載ってて、すばらしぃです

JLayerで階調反転

てゎけでさっそく、階調反転をSwingのJLayerでゃってみます

LayerUIサブクラス

最小構成

まず、LayerUIのサブクラスをかきます

JLayerを使用したコンポーネントのデコレート方法 - Oracle
LayerUIクラスのpaint()メソッドを使用すると、コンポーネントの描画方法を完全にコントロールできます。

たとぇばまったくなにもぃじらなぃpaintメソッドゎこぅです

public class InvertColorLayerUI extends LayerUI<JComponent> {
    @Override
    public void paint(Graphics g, JComponent c) {
        super.paint(g, c);
    }
}

オフスクリーンイメージの追加

Oracle公式のBlurサンプルでも、てんぷらメモの色相サンプルでも、
オフスクリーンイメージがっかゎれてます
みぇなぃ画像に先にレンダリングしとぃて、ぁとから一気に表示する、
ってゃりかたで、これゎべっにJavaにゎ限らず、
グラフィック系でゎどこででもでてくるゃりかたです

まだフィルターゎなにもかけなぃで、
オフスクリーンイメージのしくみだけ追加するとこーなります

public class InvertColorLayerUI extends LayerUI<JComponent> {
    private BufferedImage bufferedImage;
    @Override
    public void paint(Graphics g, JComponent c) {
        int w = c.getWidth();
        int h = c.getHeight();
        if (w == 0 || h == 0) return;

        //オフスクリーンイメージがなかったり大きさがちがってたら生成する
        if (bufferedImage == null
                || bufferedImage.getWidth() != w
                || bufferedImage.getHeight() != h) {
            bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        }

        //オフスクリーンイメージにコンポーネントをレンダリングする
        Graphics2D g2 = bufferedImage.createGraphics();
        g2.setClip(g.getClip());
        super.paint(g2, c);
        g2.dispose();

        //オフスクリーンイメージをそのまま画面に描画する
        Image image = c.createImage(bufferedImage.getSource());
        g.drawImage(image, 0, 0, c);
    }
}

フィルタークラスの追加

それで、オフスクリーンイメージをそのまま画面に描画するんじゃなく、
オフスクリーンイメージに対してフィルターをかけるんですけど、
フィルターゎRGBImageFilterを継承してっくるのがぃぃそぅです
ゃっとここで、階調反転そのものをかきます

https://gist.github.com/ayapi/7660869 Line:33-40

このビット演算ゎ、Aゎ関係なぃので取り出してそのままの値で、
RGBゎ取り出して反転して、
AとRGBをまたぁゎせて返しましょぅ、とゅー内容です
このへんゎSwingだからって特別なとこゎなにもなぃです/(^o^)\

paintメソッド内でフィルターを適用

それでLayerUIサブクラスのpaintメソッドの最後の描画の前で
このフィルタークラスを適用するょーにします

https://gist.github.com/ayapi/7660869 Line:25-30

これでLayerUIサブクラスゎ完成です\(^o^)/

JLayerにコンポーネントとLayerUIを指定する

たとぇばパネルをソースにしてフィルターをかけるとすれば、
こーゅーふうに指定します
(実際にっかぅ時ゎ空のパネルじゃなくてぃろ②追加するんですけど)

https://gist.github.com/ayapi/7660869 Line:48-50

そしてlayerだけを親のフレームとかにaddします
panellayerUIゎもぅaddしなぃです

完成ばん

とゅーゎけで、できたコードがこれですー!

https://gist.github.com/ayapi/7660869