我想知道如何在Java中最好地处理像素操作。我正在使用swing,并且绘制一个1x1像素的矩形非常缓慢。我需要至少达到60 fps,而不使用太多资源。首先对图像进行blitting是否意味着可以成功实现这一目标?还是用Java完成这项任务是不好的选择,我需要坚持使用C或其他替代方法吗?
我正在编写光线追踪器的初始阶段,由于我正在使用的openCL有一个Java包装器,因此我更喜欢使用Java。
我想知道如何在Java中最好地处理像素操作。我正在使用swing,并且绘制一个1x1像素的矩形非常缓慢。我需要至少达到60 fps,而不使用太多资源。首先对图像进行blitting是否意味着可以成功实现这一目标?还是用Java完成这项任务是不好的选择,我需要坚持使用C或其他替代方法吗?
我正在编写光线追踪器的初始阶段,由于我正在使用的openCL有一个Java包装器,因此我更喜欢使用Java。
在@camickr的建议上添加:
创建一个BufferedImage(BI),将其包装为IconImage,将其设置为JLabel的图标。在BI上绘制更改,并调用JLabel的repaint()将这些更改刷新到屏幕上。在BI中缓存部分图像减少了绘图例程的工作量。它只需要复制图像而不是渲染图像。使用SwingWorkers部署后台线程来运行计算并将结果传递回EDT进行绘画。
只要你谈论的是静态图像,那就可以很好地工作。如果您考虑像视频游戏一样的东西(一些固定的图像和其他移动的图像),请查看VolatileImage。这里有一个很好的描述:http://gpwiki.org/index.php/Java:Tutorials:VolatileImage
更新:
以下内容给我略高于80 fps:
public class Demo extends javax.swing.JPanel {
private Image src = null;
public Demo() {
new Worker().execute();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (src != null) g.drawImage(src, 0, 0, this);
}
private class Worker extends SwingWorker<Void, Image>{
private final Color[] colors = { Color.red, Color.green, Color.blue };
protected void process(List<Image> chunks){
for (Image bufferedImage : chunks){
src = bufferedImage;
repaint();
}
}
protected Void doInBackground() throws Exception{
int frames = 0;
int[] mem = new int[1024 * 768];
long start = System.currentTimeMillis();
long end = start + 15000;
long last = start;
while (last < end){
int col = colors[frames % colors.length].getRGB();
for (int y = 0; y < 768; y++)
for (int x = 0; x < 1024; x++)
mem[x + y * 1024] = col;
Image img = createImage(new MemoryImageSource(1024, 768, mem, 0, 1024));
BufferedImage bi = new BufferedImage(1024, 768, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = bi.createGraphics();
g2.drawImage(img, 0, 0, null);
g2.dispose();
publish(bi);
last = System.currentTimeMillis();
frames++;
}
System.err.println("Frames = " + frames + ", fps = " + ((double) frames / (last - start) * 1000));
return null;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run(){
JFrame jf = new JFrame();
jf.getContentPane().add(new Demo(), BorderLayout.CENTER);
jf.setSize(1024, 768);
jf.setVisible(true);
}
});
}
}
Frames = 7187,fps = 479.10139324045065
。 - Jack
BufferedImage
,就像@Devon_C_Miller的答案一样。而且很难想象你不能用60fps绘制一个1 x 1像素的矩形。 - class stacker