BufferedImage
source からdestination への ARGB 値の (長方形領域の) コピーを実行したいと考えていますBufferedImage
。合成は行わないでください。ARGB 値が 0x8000BE50 (アルファ値は 128) のピクセルをコピーする場合、コピー先ピクセルは正確に0x8000BE50 である必要があり、コピー先ピクセルを完全にオーバーライドします。
非常に正確な質問があり、必要なものを示すために単体テストを作成しました。単体テストは完全に機能し、自己完結型であり、問題なく合格しており、まさに私が望んでいることを行っています。
ただし、copySrcIntoDstAt (...)を置き換えるには、より高速でメモリ効率の高い方法が必要です。
それが私の質問の要点です。私は、画像をより速く「塗りつぶす」方法を求めていません(私が行ったことは、単体テストを行うための単なる例です)。私が望むのは、それを行うための高速でメモリ効率の良い方法 (つまり、高速で不要なオブジェクトを作成しない方法) を知ることだけです。
私が作成した概念実証の実装は、明らかにメモリ効率が非常に高いですが、低速です (すべてのピクセルに対して1getRGB
つと 1 つを実行します)。setRGB
概略的に、私はこれを持っています: (ここで、A はコピー前のコピー先画像からの対応するピクセルを示します)
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
そして、私はこれが欲しい:
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAABBBBAAA
AAAAAAAAAAAAABBBBAAA
AAAAAAAAAAAAAAAAAAAA
ここで、「B」はsrc画像のピクセルを表します。
APIリンク/引用ではなく、 copySrcIntoDstAt(...)メソッドの正確な代替品を探していることに注意してください。
import org.junit.Test;
import java.awt.image.BufferedImage;
import static org.junit.Assert.*;
public class TestCopy {
private static final int COL1 = 0x8000BE50; // alpha at 128
private static final int COL2 = 0x1732FE87; // alpha at 23
@Test
public void testPixelsCopy() {
final BufferedImage src = new BufferedImage( 5, 5, BufferedImage.TYPE_INT_ARGB );
final BufferedImage dst = new BufferedImage( 20, 20, BufferedImage.TYPE_INT_ARGB );
convenienceFill( src, COL1 );
convenienceFill( dst, COL2 );
copySrcIntoDstAt( src, dst, 3, 4 );
for (int x = 0; x < dst.getWidth(); x++) {
for (int y = 0; y < dst.getHeight(); y++) {
if ( x >= 3 && x <= 7 && y >= 4 && y <= 8 ) {
assertEquals( COL1, dst.getRGB(x,y) );
} else {
assertEquals( COL2, dst.getRGB(x,y) );
}
}
}
}
// clipping is unnecessary
private static void copySrcIntoDstAt(
final BufferedImage src,
final BufferedImage dst,
final int dx,
final int dy
) {
// TODO: replace this by a much more efficient method
for (int x = 0; x < src.getWidth(); x++) {
for (int y = 0; y < src.getHeight(); y++) {
dst.setRGB( dx + x, dy + y, src.getRGB(x,y) );
}
}
}
// This method is just a convenience method, there's
// no point in optimizing this method, this is not what
// this question is about
private static void convenienceFill(
final BufferedImage bi,
final int color
) {
for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
bi.setRGB( x, y, color );
}
}
}
}