Java 将BuffereImage绘制到另一个BuffereImage的最快方法

Java 将BuffereImage绘制到另一个BuffereImage的最快方法,java,performance,image-processing,bufferedimage,raster,Java,Performance,Image Processing,Bufferedimage,Raster,我正在尝试用Java创建一个图像马赛克。我计算我正在创建的新图像的大小,然后对于将成为马赛克一部分的每个子图像,我进行绘制调用 在伪代码中: create buffered image big enough to hold entire mosaic create Graphics2D context from that image for each buffered subimage that will be a part of the mosaic draw the subimage

我正在尝试用Java创建一个图像马赛克。我计算我正在创建的新图像的大小,然后对于将成为马赛克一部分的每个子图像,我进行绘制调用

在伪代码中:

create buffered image big enough to hold entire mosaic
create Graphics2D context from that image

for each buffered subimage that will be a part of the mosaic
   draw the subimage on the graphics context of big bufferedimage
   g2.drawImage(myImage, x,y,width,height,null,null)
有更好的方法吗?我希望有某种直接复制操作可用,因为我不想将子图像转换或缩放为更大的图像。类似于每个子图像的光栅阵列副本的东西。我注意到有一个setData方法可以接收光栅对象,但该方法注意到光栅必须位于相同的坐标空间中

有什么想法吗?这是我的程序中的一个瓶颈,我希望它尽可能快

编辑: 事实证明,关于瓶颈在哪里,我错了(在没有硬数据的情况下进行假设时通常是这样)。我有一个错误,多个3MB图片被反复读取,而不是使用内存中缓存的图像的缩小版本。当我进行修复时,我的运行时间从50分钟变为15秒。

您可以拨打

getPixels(int x, int y, int w, int h, int[] iArray)
在子图像的光栅上,然后

setPixels(int x, int y, int w, int h, int[] iArray)
在较大图像的可写光栅上。至于效率或性能,我不知道。你得自己测试一下。当然,图像必须是相同的类型(相同的颜色空间、相同的分辨率等),但听起来您已经假设了。

通常,drawImage()调用将直接映射到硬件加速的blit操作上。根据您使用的驱动程序/图形卡和JVM,扩展也应该是硬件加速的。但是,如果您可以避免缩放,那么您当然应该这样做


如果子图像确实适合较大的图像,您应该能够通过选择宽度和高度来避免缩放,使其与子图像的宽度和高度相同,当然在这种情况下,您最好使用g.drawImage(图像img、int x、int y、ImageObserver).

我强烈建议人们使用上面Marc的建议,因为它允许操作停留在硬件加速的管道中。将图像中的像素提取到一个Java数组中,并按照上面的建议再次将其推出,实际上需要两件坏事;1它要求将图像从易失性VRAM空间中拉出,不再进行硬件加速(getRGB也这样做),并且要求将像素值转换为int,并从本机空间拉入JVM空间。这可能是将像素数据从一幅图像复制到另一幅图像的最慢的方法。注意:这不是对Adam建议的一种冲击,Java图像中有很多未知的特殊行为,除非您深入研究Swing/Java2D API,否则您永远不会知道(Javadoc中没有提到它们)。