Java:如何快速复制BufferedImage的像素? (包括unit testing)
我想从源BufferedImage
到目标BufferedImage
复制(矩形区域)ARGB值。 不应该进行合成:如果我复制ARGB值为0x8000BE50(alpha值为128)的像素,则目标像素必须正好为 0x8000BE50,完全覆盖目标像素。
我有一个非常精确的问题,我做了一个unit testing来展示我需要的东西。 unit testingfunction齐全,设备齐全,传递良好,正是我想要的。
但是,我想要一种更快,更有效的内存方法来替换copySrcIntoDstAt (…)。
这就是我的问题的全部要点:我不是在追求如何以更快的方式“填充”图像(我所做的仅仅是进行unit testing的一个例子)。 我想要的只是知道什么是快速和内存有效的方法(即快速而不是创建不必要的对象)。
我所做的概念validation实现显然非常节省内存,但速度很慢(为每个像素执行一次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 = 3 && x = 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 ); } } } }
private static void copySrcIntoDstAt(final BufferedImage src, final BufferedImage dst, final int dx, final int dy) { int[] srcbuf = ((DataBufferInt) src.getRaster().getDataBuffer()).getData(); int[] dstbuf = ((DataBufferInt) dst.getRaster().getDataBuffer()).getData(); int width = src.getWidth(); int height = src.getHeight(); int dstoffs = dx + dy * dst.getWidth(); int srcoffs = 0; for (int y = 0 ; y < height ; y++ , dstoffs+= dst.getWidth(), srcoffs += width ) { System.arraycopy(srcbuf, srcoffs , dstbuf, dstoffs, width); } }