この質問の回答の多くは、多くのオフサイトリソースを指しているので、私はここで完全な実装を提供すると考えました。これは本質的にあなたが見たブレンドモードの大きなライブラリと同じですが、私は特定のブレンドモードを実装する目的だけの抽象化を取り除いています。
以下のコードについていくつかの注意事項:
私のニーズのための2つの間で異なるものは何もありませんので、MultiplyComposite
クラスはComposite
とCompositeContext
の両方を実装するだけ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();
}
は、すでにjava.awt.imageでの内容を見たことがありますか? BufferedImageFilterとBufferedImageOpが適切でない何らかの理由はありますか? – DJClayworth