Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java快速像素操作_Java_Performance_Swing_Draw_Pixel - Fatal编程技术网

Java快速像素操作

Java快速像素操作,java,performance,swing,draw,pixel,Java,Performance,Swing,Draw,Pixel,我想知道如何在Java中最好地处理像素操作。我正在使用swing,绘制一个1×1像素的矩形非常慢。我需要得到60 fps至少,而不使用太多的资源。首先对一张图片进行闪电扫描是否意味着可以成功归档?或者说,用Java实现这一点总体上是个坏主意,我是否需要坚持使用C或其他替代方法 我刚开始写一个raycaster,因为我正在使用的openCL有一个Java包装器,所以我更喜欢在Java中工作。使用BufferedImage和setRGB(…)方法。然后在绘制例程中绘制整个图像。添加@camickr的

我想知道如何在Java中最好地处理像素操作。我正在使用swing,绘制一个1×1像素的矩形非常慢。我需要得到60 fps至少,而不使用太多的资源。首先对一张图片进行闪电扫描是否意味着可以成功归档?或者说,用Java实现这一点总体上是个坏主意,我是否需要坚持使用C或其他替代方法


我刚开始写一个raycaster,因为我正在使用的openCL有一个Java包装器,所以我更喜欢在Java中工作。

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

添加@camickr的建议:

创建一个BuffereImage(BI),将其包装在图标图像中,将其设置为JLabel的图标。在BI上绘制更改并调用JLabel的repaint()以刷新这些更改。对屏幕的更改。在BI中缓存部分图像可以减少绘制例程的工作量。它只需要blit图像,而不是渲染图像。使用SwingWorkers部署后台线程来运行计算,并将结果传递回EDT进行绘制

只要你说的是静态图像,那就行了。如果你正在考虑一些更像电子游戏的东西(一些固定图像和其他运动图像),请看一下VolatileImage。这里有一个很好的描述:

更新:

以下是80多帧的画面:

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);
            }
        });
    }
}
公共类演示扩展了javax.swing.JPanel{
私有映像src=null;
公共演示(){
新工作者().execute();
}
受保护组件(图形g){
超级组件(g);
如果(src!=null)g.drawImage(src,0,0,this);
}
私有类Worker扩展SwingWorker{
私有最终颜色[]颜色={Color.red,Color.green,Color.blue};
受保护的无效进程(列表块){
用于(图像缓冲区图像:块){
src=缓冲图像;
重新油漆();
}
}
受保护的Void doInBackground()引发异常{
int帧=0;
int[]mem=新int[1024*768];
长启动=System.currentTimeMillis();
长端=起点+15000;
持久=开始;
while(最后<结束){
int col=colors[frames%colors.length].getRGB();
对于(int y=0;y<768;y++)
对于(int x=0;x<1024;x++)
mem[x+y*1024]=列;
Image img=createImage(新的MemoryImageSource(1024768,mem,01024));
BuffereImage bi=新的BuffereImage(1024768,BuffereImage.TYPE_INT_ARGB);
Graphics2D g2=bi.createGraphics();
g2.drawImage(img,0,0,null);
g2.dispose();
出版(bi);
last=System.currentTimeMillis();
frames++;
}
System.err.println(“Frames=“+Frames+”,fps=“+((双)帧/(上次-开始)*1000));
返回null;
}
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
JFrame jf=新JFrame();
jf.getContentPane().add(新的Demo(),BorderLayout.CENTER);
设置大小(1024768);
jf.setVisible(真);
}
});
}
}

我可以通过这种方式(以1024x768的分辨率)满足要求(60 fps)吗?我建议阅读中间图像的概念。这里有一个例子——我认为中间图像技术与我所描述的一样;快速播放图像。但是我不熟悉Java中的speedresults,这正是我想知道的。这种技术在Java中不会得到60 fps的结果,仍然太慢。我不确定这里的这些评论如何与下面选择的答案结合在一起。@mre建议的中间映像引用部署了
BufferedImage
,就像@Devon_C_Miller的答案一样。很难想象你不能用60帧的速度画一个1 x 1像素的矩形。我在1024x768图像上用10帧的像素填充屏幕。你知道怎么加快速度吗?我正在使用你所说的技术,并运行while-true循环进行渲染。如果只渲染到BI,而不实际将其绘制到屏幕上,会获得什么样的性能?通常,光线跟踪中的瓶颈更多地出现在计算中,而不是屏幕更新中。每次完成一个屏幕的计算时,请尝试输出System.currentTimeMillis()。我正在绘制未计算的像素,所以只需逐个像素地填充屏幕即可。在320x240时,我获得100+fps,在1024x768时下降到10。如果我省略repaint(),它不会改变结果。太棒了!非常感谢你。还不知道主要区别是什么;我想这可能是一个SwingWorker的使用。交换x和y循环的顺序以使其更快(更好的局部性)。