Java快速像素操作

Rob*_*ock 11 java performance swing pixel draw

我想知道如何在Java中处理最佳的像素操作.我正在使用swing并绘制一个1 x 1像素的矩形非常慢.我需要至少获得60 fps,而不需要使用太多资源.对图像的影响首先意味着这可以成功地取得成功吗?或者用Java做这件事一般是个坏主意我是否需要坚持使用C或其他替代方案?

我正在编写一个raycaster的开头,因为我正在使用的openCL有一个Java包装器,我更喜欢用Java工作.

cam*_*ckr 5

使用 BufferedImage 和 setRGB(...) 方法。然后,您在绘画例程中绘制整个图像。


Dev*_*ler 5

添加到@ camickr的建议:

创建一个BufferedImage(BI),将其包装在IconImage中,将其设置为JLabel的图标.将更改绘制到BI上并调用JLabel的repaint()来刷新它们.更改屏幕.在BI中缓存部分图像会减少绘制例程的工作量.它只需要对图像进行blit,而不是渲染图像.使用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);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 交换x和y循环的顺序使这更快(更好的位置). (2认同)