Я хочу сделать копию (прямоугольной области) значений ARGB из источника BufferedImage
в пункт назначения BufferedImage
. Компоновка не должна выполняться: если я копирую пиксель со значением ARGB 0x8000BE50 (альфа-значение при 128), то целевой пиксель должен быть точно 0x8000BE50, полностью перекрывая целевой пиксель.
У меня очень точный вопрос, и я провел модульный тест, чтобы показать, что мне нужно. Модульный тест полностью функционален и самодостаточен, проходит нормально и выполняет именно то, что я хочу.
Однако я хочу более быстрый и более эффективный для памяти метод , чтобы заменить copySrcIntoDstAt (...).
В этом весь мой вопрос: я не понимаю, как «заполнить» изображение более быстрым способом (то, что я сделал, это просто пример проведения юнит-теста). Все, что я хочу, это знать, что было бы быстрым и эффективным с точки зрения памяти способом сделать это (то есть быстро и без создания ненужных объектов).
Реализация концепции, которую я сделал, очевидно, очень эффективна для использования памяти, но она медленная (выполнение одного getRGB
и одного setRGB
для каждого пикселя).
Схематично, у меня есть это: (где A указывает соответствующие пиксели от конечного изображения до копирования)
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
И я хочу иметь это:
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAABBBBAAA
AAAAAAAAAAAAABBBBAAA
AAAAAAAAAAAAAAAAAAAA
, где 'B' представляет пиксели из src изображения.
Обратите внимание, что я ищу точную замену метода copySrcIntoDstAt (...) , а не ссылки / цитаты API.
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 );
}
}
}
}