【问题标题】:Fastest way to draw BufferedImages to another BufferedImage将 BufferedImage 绘制到另一个 BufferedImage 的最快方法
【发布时间】:2010-07-04 18:53:36
【问题描述】:

我正在尝试在 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)

有没有更好的方法来做到这一点?我希望有某种直接复制操作可用,因为我不想将子图像转换或缩放成更大的图像。类似于每个子图像的光栅的arraycopy。我注意到有一个接受 Raster 对象的 setData 方法,但该方法指出 Raster 必须位于相同的坐标空间中。

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

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

【问题讨论】:

    标签: java performance image-processing bufferedimage raster


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      你可以打电话

      getPixels(int x, int y, int w, int h, int[] iArray)
      

      在子图像的光栅上,然后

      setPixels(int x, int y, int w, int h, int[] iArray)
      

      在 WritableRaster 上获取更大的图像。至于效率或性能,我不知道。你必须自己测试它。当然,图像必须是相同的类型(相同的色彩空间、相同的分辨率等),但听起来您已经假设了。

      【讨论】:

      • 我强烈建议人们使用上述 Marc 的建议,因为它允许操作停留在硬件加速管道中。将像素从图像中拉出到 Java 数组中,然后按照上面的建议将它们再次推出,实际上需要两件坏事; 1 它需要将图像拉出易失性 VRAM 空间并且不再进行硬件加速(getRGB 也这样做),并且需要将像素值转换为 int 并从本机空间拉到 JVM 空间。这可能是将像素数据从一张图像复制到另一张图像的最慢方法。
      • 注意:这不是对 Adam 的建议,Java 图像中隐藏着许多未知的特殊行为,除非您深入研究过 Swing/Java2D API,否则您永远不会知道 ( Javadoc 中没有提到它们)。
      猜你喜欢
      • 2018-03-03
      • 1970-01-01
      • 2015-03-12
      • 2022-01-21
      • 2013-09-02
      • 2022-01-20
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      相关资源
      最近更新 更多