将 BufferedImage 绘制到另一个 BufferedImage 的最快方法
我正在尝试用 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 方法接受 Raster 对象,但该方法指出 Raster 必须位于相同的坐标空间中。
有什么想法吗?这是我的程序中的一个瓶颈,我希望它尽可能快。
编辑: 事实证明,我对瓶颈所在的判断是错误的(在没有硬数据的情况下做出假设时经常出现这种情况)。我遇到了一个错误,即一遍又一遍地读取多张 3MB 图片,而不是使用内存中缓存的缩小版图像。当我进行修复时,我的运行时间从 50 分钟缩短到 15 秒。
I am attempting to create a mosaic of images in Java. I calculate the size of the new image I'm creating, and then for each subimage that will be part of the mosaic, I do a paint call.
In pseudocode:
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)
Is there a better way to do this? I'd hope there's some sort of direct copying operation available, since I don't want to transform or scale the subimages into the bigger image. Something akin to an arraycopy of the rasters of each subimage. I notice there's a setData method that takes in a Raster object, but the method notes that the Raster has to be in same coordinate space.
Any thoughts? This is a bit of a bottleneck in my program and I'd like it to be as fast as possible.
EDIT:
It turns out I was wrong (as is often the case when assumptions are made without hard data) about where the bottleneck was. I had a bug where multiple 3MB pictures were being read over and over again rather than using the scaled down versions of the images cached in memory. My running time went from 50 minutes to 15 seconds when I made the fix.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常,drawImage() 调用将直接映射到硬件加速的 blit 操作。根据您使用的驱动程序/显卡和 JVM,缩放也应该是硬件加速的。但是,如果您可以避免缩放,那么您当然应该这样做。
如果子图像确实适合较大的图像,您应该能够通过选择宽度和高度来避免缩放,使它们与子图像的宽度和高度相同,当然在这种情况下您最好使用 g.drawImage(图像img,int x,int y,ImageObserver观察者)。
Typically the drawImage() call will directly map on a hardware accelarated blit operation. Depending on the driver/graphics card and JVM you are using, also scaling should be hardware accelerated. However if you can avoid scaling you should of course.
If the sub-images do fit in the larger image you should be able to avoid scaling by choosing your width and height such that they are the same as that of the subimage, of course in this case you are better of using g.drawImage(Image img, int x, int y, ImageObserver observer).
您可以
调用子图像的 Raster,然后
调用较大图像的 WritableRaster。但至于效率或性能,我不知道。你必须自己测试一下。当然,图像必须是相同的类型(相同的色彩空间、相同的分辨率等),但听起来您已经假设了这一点。
You could call
on the Raster for the subimage and then
on the WritableRaster for the larger image. As for efficiency or performance, though, I have no idea. You'd have to test it yourself. Of course, the images would have to be the same type (same color space, same resolution, etc.) but it sounds like you're already assuming that.