Graphics2D.drawImage在java 8上非常慢



我看过一些与这个问题相关的线程,特别是在这里和这里,然而,第一个问题是在许多年前被问到的(甚至在java 7之前),第二个问题是关于绘制单一颜色的简化情况,它提供了一个更好的解决方案,即使用Graphics.fillRect

我也尝试了一些建议在第一个线程,如使用兼容的图像格式在我的情况下,我已经在使用它(TYPE_INT_ARGB),我也试着告诉java使用openGL;这一个有一个很酷的结果,渲染我的大部分应用程序作为一个黑色的窗口…

所以我在这里再次问这个问题,希望能找到一个更好的解决方案。

问题来了:

我正在研究一个应用程序,需要根据用户交互绘制新的自动生成和不断变化的图像。用户交互倾向于以糟糕的4-10fps运行,我将罪魁祸首缩小到对Graphics2D.drawImage的调用,这个函数在合理的时间内开始运行,不到10毫秒,但很快,在前2-3个调用之后,增加到250毫秒以上。图像本身的大小可以有所不同,但在我的测试中始终小于1000x1000像素,并且是BufferedImage,使用类型TYPE_INT_ARGB,这是我系统的兼容类型。任何帮助,这将是非常感激!

根据要求,这里是一个最小的可复制示例:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class LowFPS {
public static final int SIZE = 700;
public static final BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
public static void main(String args[]) {
JFrame frame = new JFrame("Low FPS Example");
JComponent view = new ImageComponent();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(view, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static class ImageComponent extends JComponent {
public ImageComponent() {
setPreferredSize(new Dimension(SIZE, SIZE));
setOpaque(true);
addMouseMotionListener(
new MouseMotionListener() {
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
double start = System.nanoTime()/1e9;
int raster[] = new int[SIZE*SIZE];
int g = 0;
Random rand = new Random();
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
g = rand.nextInt(156)+100;
raster[SIZE*j+i] = (0xff << 24) | (g << 16) | (g << 8) | g;
}
}
synchronized(image) {
image.getRaster().setDataElements(
0, 0, SIZE, SIZE, raster
);
}
double stop = System.nanoTime()/1e9;
System.out.printf("generate time: %fn", stop-start);
ImageComponent.this.repaint();
}
}
);
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
synchronized(image) {
double start = System.nanoTime()/1e9;
g2.drawImage(image, null, 0, 0);
double stop = System.nanoTime()/1e9;
System.out.printf("draw time: %fn", stop-start);
}
}
}
}

这里是我运行这个得到的一些输出:

draw time: 0.005215
draw time: 0.003509
generate time: 0.025820
generate time: 0.009886
draw time: 0.001034
generate time: 0.008111
generate time: 0.007449
draw time: 0.000753
generate time: 0.005950
generate time: 0.005828
draw time: 0.000670
generate time: 0.005807
generate time: 0.005737
draw time: 0.000619
generate time: 0.005666
draw time: 0.000657
generate time: 0.005559
draw time: 0.000530
generate time: 0.005521
draw time: 0.000508
generate time: 0.005455
draw time: 0.000487
generate time: 0.005410
draw time: 0.002473
generate time: 0.005392
generate time: 0.005406
draw time: 0.011764
generate time: 0.006291
generate time: 0.006608
draw time: 0.042349
generate time: 0.016228
generate time: 0.010290
draw time: 0.111547
generate time: 0.016587
generate time: 0.010646
draw time: 0.240194
generate time: 0.016043
generate time: 0.010762
draw time: 0.125226
generate time: 0.016076
generate time: 0.010350
draw time: 0.104254
generate time: 0.015372
generate time: 0.009877
draw time: 0.234022
generate time: 0.016878
generate time: 0.010765
draw time: 0.103371
generate time: 0.015868
generate time: 0.010262
draw time: 0.232200
generate time: 0.015839
generate time: 0.009695
draw time: 0.118478
generate time: 0.015144
generate time: 0.009925
draw time: 0.100979
generate time: 0.015897
generate time: 0.010610
draw time: 0.245413
generate time: 0.015212
generate time: 0.009755
draw time: 0.123311
generate time: 0.014929
generate time: 0.009887
draw time: 0.115697
generate time: 0.016013
generate time: 0.010928
draw time: 0.251448
generate time: 0.015607
generate time: 0.010624
draw time: 0.117246
generate time: 0.015960
generate time: 0.010239
draw time: 0.117721
generate time: 0.016382
generate time: 0.010506
draw time: 0.122491
generate time: 0.015746
generate time: 0.010153
draw time: 0.117414
generate time: 0.015598
generate time: 0.010362
draw time: 0.117872
generate time: 0.015859
generate time: 0.010637
draw time: 0.113869
generate time: 0.016953
generate time: 0.010780
draw time: 0.111810
generate time: 0.016389
generate time: 0.010655
draw time: 0.246486
generate time: 0.016682
generate time: 0.010737
draw time: 0.121975
generate time: 0.015779
generate time: 0.010437
draw time: 0.125625
generate time: 0.016359
generate time: 0.010636
draw time: 0.221910
generate time: 0.016156
generate time: 0.010369
draw time: 0.122495
generate time: 0.016397
generate time: 0.010612
draw time: 0.238445
generate time: 0.015114
generate time: 0.009899
draw time: 0.113739
generate time: 0.015389
generate time: 0.010127
draw time: 0.126756
generate time: 0.018503
generate time: 0.011559
draw time: 0.243606
generate time: 0.016405
generate time: 0.010426
draw time: 0.116460
generate time: 0.015355
generate time: 0.010080
draw time: 0.119474
generate time: 0.016397
generate time: 0.010536
draw time: 0.258496
generate time: 0.015853
generate time: 0.010504
draw time: 0.102392
generate time: 0.021260
generate time: 0.009640
draw time: 0.121522
generate time: 0.015351
generate time: 0.009437
draw time: 0.119224
generate time: 0.015698
generate time: 0.010410
draw time: 0.113848
generate time: 0.014471
generate time: 0.009880
draw time: 0.241783
generate time: 0.016351
generate time: 0.010552
draw time: 0.127653
generate time: 0.016064
generate time: 0.010969
draw time: 0.127003
generate time: 0.014897
generate time: 0.009697
draw time: 0.251630
generate time: 0.015527
generate time: 0.010259
draw time: 0.111767
generate time: 0.015485
generate time: 0.010329
draw time: 0.123999
generate time: 0.014251
generate time: 0.009680
draw time: 0.239466
generate time: 0.015720
generate time: 0.011239
draw time: 0.112809
generate time: 0.015376
generate time: 0.010115
draw time: 0.113489
generate time: 0.015563
generate time: 0.010294
draw time: 0.117295
generate time: 0.013725
generate time: 0.009450
draw time: 0.123859
generate time: 0.014134
generate time: 0.009614
draw time: 0.237366
generate time: 0.014752
generate time: 0.010723
draw time: 0.120068
generate time: 0.014044
draw time: 0.129768

正如你所看到的,生成时间能够支持至少50fps,但是绘制图像所需的时间将帧速率降低到约8fps。

在EDT上做任何额外的延迟处理都会减慢速度。同步也不例外。我怀疑EDT上的处理任务正在被备份(排队等待处理)。我建议你修改这个:

synchronized(image) {
image.getRaster().setDataElements(
0, 0, SIZE, SIZE, raster
);
}

image.getRaster().setDataElements(
0, 0, SIZE, SIZE, raster);

并且去掉paintComponent中的同步。除非您在另一个线程中修改光栅,否则这是不必要的。只有一个Event Dispatch Thread, EDT上的所有事件都是连续发生的。

最新更新