2009-03-12 10 views
4

2つの異なるjavax.swing.Iconオブジェクトがあります。これらの2つのコンポジットである新しいアイコンを作成したいと思います。コンポジットは、そのオプションを選択したときにPhotoshopのような画像編集アプリケーションで表示されるものと同じように、マルチプレイ効果が欲しいです。具体的には、すべてのピクセルあたり、あなたは画像1と画像から色Ca及びCbのを持っている場合、それぞれGraphics2Dを使用してMULTIPLYコンポジットエフェクトを実行する方法

CA =(Raは、GA、BA) Cbの=(RB、GB、BB)

iが出力したいです

CC =(RaはRB、ジョージア GB、Baの* BB)

であることを私は(リアルタイムで)その場でこれをやりたいので、私はこれだけのGraphics2Dの操作を使用しないようになってきました。私はAlphaCompositeを見てきましたが、これができるかどうかわかりません。誰にでもアイデアはありますか?

+0

は、すでにjava.awt.imageでの内容を見たことがありますか? BufferedImageFilterとBufferedImageOpが適切でない何らかの理由はありますか? – DJClayworth

答えて

0

この質問の回答の多くは、多くのオフサイトリソースを指しているので、私はここで完全な実装を提供すると考えました。これは本質的にあなたが見たブレンドモードの大きなライブラリと同じですが、私は特定のブレンドモードを実装する目的だけの抽象化を取り除いています。

以下のコードについていくつかの注意事項:

  • 私のニーズのための2つの間で異なるものは何もありませんので、MultiplyCompositeクラスはCompositeCompositeContextの両方を実装するだけg.setComposite(MultiplyComposite.Multiply)

  • を使用するには。パラメータの調整が可能なブレンドモードがある場合、またはブレンドが異なる場合は、2つのクラスを別々に実装する必要があります。

  • このコードは、32ビットの「整数」バッファでのみ機能します。これを変更して16ビットカラー(8ビットではなく5/6ビットのシフトとマスキング)を使用するように変更する必要があります。

  • このコードは最後のバイトをアルファチャンネルとして使用します。アルファチャンネル(24ビット)なしでデータを操作するには、コードを変更する必要があります。

  • mixPixelメソッドで8分の1の右シフトは、256で分ける簡単な方法です。 (a * b) >> 8の代わりに(a * b)/256

  • ピクセルは左から右に一度に1行ずつ処理されます。より多くのメモリがある場合、これを変更してバッファ全体を一度に処理することができます。


public class MultiplyComposite implements Composite, CompositeContext { 
    protected void checkRaster(Raster r) { 
     if (r.getSampleModel().getDataType() != DataBuffer.TYPE_INT) { 
      throw new IllegalStateException("Expected integer sample type"); 
     } 
    } 

    @Override 
    public void compose(Raster src, Raster dstIn, WritableRaster dstOut) { 
     checkRaster(src); 
     checkRaster(dstIn); 
     checkRaster(dstOut); 

     int width = Math.min(src.getWidth(), dstIn.getWidth()); 
     int height = Math.min(src.getHeight(), dstIn.getHeight()); 
     int x, y; 
     int[] srcPixels = new int[width]; 
     int[] dstPixels = new int[width]; 

     for (y=0; y < height; y++) { 
      src.getDataElements(0, y, width, 1, srcPixels); 
      dstIn.getDataElements(0, y, width, 1, dstPixels); 

      for (x=0; x < width; x++) { 
       dstPixels[x] = mixPixel(srcPixels[x], dstPixels[x]); 
      } 

      dstOut.setDataElements(0, y, width, 1, dstPixels); 
     } 
    } 

    private static int mixPixel(int x, int y) { 
     int xb = (x) & 0xFF; 
     int yb = (y) & 0xFF; 
     int b = (xb * yb)/255; 

     int xg = (x >> 8) & 0xFF; 
     int yg = (y >> 8) & 0xFF; 
     int g = (xg * yg)/255; 

     int xr = (x >> 16) & 0xFF; 
     int yr = (y >> 16) & 0xFF; 
     int r = (xr * yr)/255; 

     int xa = (x >> 24) & 0xFF; 
     int ya = (y >> 24) & 0xFF; 
     int a = Math.min(255, xa + ya); 

     return (b) | (g << 8) | (r << 16) | (a << 24); 
    } 


    @Override 
    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) { 
     return this; 
    } 

    @Override 
    public void dispose() { 

    } 

    public static final MultiplyComposite Multiply = new MultiplyComposite(); 

} 
関連する問題