我正在尝试从渲染管道中挤出更多性能。 (到目前为止)最慢的部分是在大图像上执行 java.awt.imaging.LookupOp。
图像尺寸约为2048x2048。
我发现将过滤器与绘图操作一起完成比调用过滤器方法要快得多。然而,这仍然给我们留下了大约需要 250 毫秒(或 4 fps)的查找操作。有没有人有任何渲染技巧?
这基本上是我们正在做的事情:
public void paint(Graphics g)
{
if(recalcLUT)
{
Graphics2D g2d = (Graphics2D) displayImage.getGraphics();
g2d.drawImage(srcImage, lut, 0, 0);
}
Graphics2D g2d = (Graphics2D) g;
g2d.clearRect(0, 0, this.getWidth(), this.getHeight());
AffineTransform at = new AffineTransform();
at.setToIdentity();
at.scale(scale, scale);
g2d.drawImage(displayImage, at, null);
}
lut变量是一个LookupOp,通常是一个ShortLookupOp,图像是16位灰度图像
谢谢
我知道这里还可以进行一些其他明显的性能优化。但主要问题是执行 LookupOp 操作,因此我正在寻求与此相关的建议。
查找操作本质上是创建一个数组,而不是将图像的每个像素渲染为其颜色,而是使用颜色作为数组的索引并将颜色渲染为索引中的值。在这个特定的示例中,我使用它来执行一些简单的亮度/对比度操作。 您还可以使用 rescaleOp 来实现这一点,这本质上是一种将线性函数应用于所有像素值的方法。但事实证明这会慢一些。
最佳答案
我已经有近八年没有使用 java 了,所以某些语法可能不相关。
关于循环的任何性能的关键是将尽可能多的东西推到循环之外。如果不能,则仅在它们发生变化时才执行计算。通常最好等到最后一刻重新计算,以便可以缓存多个更改。
将所有对象构造移到渲染循环之外。如果你事先知道需要多少个对象,那么就将它们传入;如果不这样做,则使用对象池并让工厂在渲染循环之外创建对象。这将节省您的构建/销毁时间。
仅在比例发生变化时才计算 AffineTransform。将其推到绘制循环之外并将其传入(作为 const 引用...它们是否存在于 Java 中?我已经使用 C++ 太久了)
您可能不需要调用 at.setToIdentity(),因为您的 AffineTransform 应默认为单位矩阵(选中此项)
是否需要每帧调用 recalcLUT?执行if语句后将recalcLUT设置为false是否有意义?
我不确定 LookupOp 的目标是什么。如果您给我更多关于它正在做什么的信息,我也许可以提出更多建议。
希望这有帮助。
关于java - 查找操作性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/264312/