当前位置: 首页 > 知识库问答 >
问题:

无法加速像素修改的BufferedImage

索嘉胜
2023-03-14

很长一段时间,1-2个月,我一直试图找到这个问题的答案:

我的图像硬件无法加速!

我一直在网上搜索,创造了我自己的方法,用键盘敲我的头(仍然感到疼痛),但没有成功。

虽然我讨厌Java SDK以外的库,但我尝试了LWJGL和JOGL,但由于一些愚蠢的原因,它们在我的计算机上不起作用。

我试着使用系统。setProperty(“Dsun.java2d.opengl”,“True”),我使用了VolatileImage,但我无法为其绘制单个像素。(我试着使用绘图线(x,y,x,y),但速度很慢)

现在我是如此绝望。我会做任何事情来解决这个问题!所以,如果你知道解决方案(我知道你们中的一些人知道),请告诉我,这样我就可以摆脱这个。

我的代码:

   public static void render(int x, int y, int w, int h, ) {

            int a[] = new int[3]; // The array that contains RGB values for every pixel
            BufferedImage bImg = Launcher.contObj.getGraphicsConfiguration().createCompatibleImage(800, 600, Transparency.TRANSLUCENT); // Creates an image compatible to my JPanel (Runs at 20-24 FPS on 800x600 resolution)
            int[] wr = ((DataBufferInt) bImg.getRaster().getDataBuffer()).getData(); // Contains the image data, used for drawing pixels
            for (int i = 0; i < bImg.getWidth(); i++) {
                for (int j = 0; j < bImg.getHeight(); j++) {
                    a[0] = i % 256;
                    a[2] = j % 256;
                    a[1] = i * j % 256;
                    wr[i + j * bImg.getWidth()] = new Color(a[0], a[1], a[2]).getRGB(); // Sets the pixels from a[]
                }
            }
            bImg.flush();
            g.drawImage(bImg, x, y, w, h, null); // Draws the image on the JPanel
            g.dispose();
            System.out.println(bImg.getCapabilities(Launcher.contObj.getGraphicsConfiguration()).isAccelerated()); // Prints out whether I was successful and made the image accelerated or failed and made everything worse
        }

我希望您理解代码。请以任何方式修改它,以帮助我找到问题的解决方案。

注意:请不要发布任何关于外部库的信息,除非你绝对确定没有它们我就无法工作。

还有,是不是我的显卡不支持加速?(因为我看到了一些帖子,其中hardware accel适用于其他人,但不适用于我)顺便说一句,这是一款GeForce 430 GT。

提前感谢!

共有1个答案

澹台俊晖
2023-03-14

来源复制自:Java硬件加速不适用于英特尔集成显卡

试试这个:

package graphicstest;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;

public class GraphicsTest extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GraphicsTest();
            }
        });
    }

    GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    BufferCapabilities bufferCapabilities;
    BufferStrategy bufferStrategy;

    int y = 0;
    int delta = 1;

    public GraphicsTest() {

        setTitle("Hardware Acceleration Test");
        setSize(500, 300);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        setVisible(true);

        createBufferStrategy(2);
        bufferStrategy = getBufferStrategy();

        bufferCapabilities = gc.getBufferCapabilities();

        new AnimationThread().start();
    }

    class AnimationThread extends Thread {
        @Override
        public void run() {

            while(true) {
                Graphics2D g2 = null;
                try {
                    g2 = (Graphics2D) bufferStrategy.getDrawGraphics();
                    draw(g2);
                } finally {
                    if(g2 != null) g2.dispose();
                }
                bufferStrategy.show();

                try {
                    // CHANGE HERE, DONT SLEEP
                    //Thread.sleep(16);
                } catch(Exception err) {
                    err.printStackTrace();
                }
            }
        }
    }

    public void draw(Graphics2D g2) {
        if(!bufferCapabilities.isPageFlipping() || bufferCapabilities.isFullScreenRequired()) {
            g2.setColor(Color.black);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setColor(Color.red);
            g2.drawString("Hardware Acceleration is not supported...", 100, 100);
            g2.setColor(Color.white);
            g2.drawString("Page Flipping: " + (bufferCapabilities.isPageFlipping() ? "Available" : "Not Supported"), 100, 130);
            g2.drawString("Full Screen Required: " + (bufferCapabilities.isFullScreenRequired() ? "Required" : "Not Required"), 100, 160);
            g2.drawString("Multiple Buffer Capable: " + (bufferCapabilities.isMultiBufferAvailable() ? "Yes" : "No"), 100, 190);
        } else {
            g2.setColor(Color.black);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setColor(Color.white);
            g2.drawString("Hardware Acceleration is Working...", 100, 100);
            g2.drawString("Page Flipping: " + (bufferCapabilities.isPageFlipping() ? "Available" : "Not Supported"), 100, 130);
            g2.drawString("Full Screen Required: " + (bufferCapabilities.isFullScreenRequired() ? "Required" : "Not Required"), 100, 160);
            g2.drawString("Multiple Buffer Capable: " + (bufferCapabilities.isMultiBufferAvailable() ? "Yes" : "No"), 100, 190);
        }

        y += delta;
        if((y + 50) > getHeight() || y < 0) {
            delta *= -1;
        }

        g2.setColor(Color.blue);
        g2.fillRect(getWidth()-50, y, 50, 50);
    }
}

输出我的硬件加速不可用。java.exe占用了12%的CPU。700 FPS

然后我添加了系统变量:

Variable name: J2D_D3D_NO_HWCHECK
         Variable value: true

然后重启IDE,运行程序:

我得到了惊人的结果。我有可用的硬件加速。Java语言exe占用了5%的CPU。1700 FPS。动画很棒!

以上内容是为了检查硬件加速是否在您的系统中工作。

现在谈谈你的问题:

AFAIK:使用BuffereImage无法获得真正的硬件加速。您应该使用VolatileImage来获得硬件加速。但使用VolatileImage,您无法获取像素数据缓冲区来修改像素。使用硬件逐像素渲染也没有意义。

我的建议:

1)设计你的逻辑,可以使用易失性图像的图形和图形2D渲染像素。但是不要像画1像素的线一样去做黑客。

2) 使用缓冲策略,双/三缓冲。

3) 如果要使用BuffereImage设置每个像素,请使用BuffereImage作为数据模型,同时在volatile image上渲染绘制缓冲图像。如果您正在缩放图像,这将有很大帮助。

4) 缓存频繁渲染的图像。

5) 更好地编写代码,例如:

int wi = bImg.getWidth();
int he = bImg.getHeight();
for (int i = 0; i < wi; i++) {
    for (int j = 0; j < he; j++) {
        wr[i + j * wi] = ((i % 256) << 16) | ((i * j % 256) << 8) | (j % 256);
    }
}

6) 对于sqrt()、sin()、cos()等耗时的数学操作,请缓存这些操作的结果并创建查找表。

 类似资料:
  • 我面临毕加索无法快速加载图像的问题。 有3个显示左、中、右图像。在快进/后退时,对于给定的时间点,选择左、中、右并显示在三个框中。 这是初始化。缓存是100MB以及99MB的 窗口移动的图像数是3000。所以我将图像预加载为 平均图像大小为10KB-320x180,因此达到35MB,小于99MB。 当快速循环工作时,许多图像是(来自)和(来自),但在几个快速循环之后,3个图像冻结或变得非常慢。此时

  • 本文向大家介绍详解docker国内镜像拉取和镜像加速registry-mirrors配置修改,包括了详解docker国内镜像拉取和镜像加速registry-mirrors配置修改的使用技巧和注意事项,需要的朋友参考一下 由于国内访问直接访问Docker hub网速比较慢,拉取镜像的时间就会比较长。一般我们会使用镜像加速或者直接从国内的一些平台镜像仓库上拉取。 我比较常用的是网易的镜像中心和daoc

  • 问题内容: 在Python中遍历列表时,如果没有列表理解,就无法修改元素。以供参考: 那么,为什么不能通过Python中的循环修改元素?肯定有一些我想念的东西,但是我不知道是什么。我确定这是重复的,但是我找不到与此相关的问题,如果有链接,那就绰绰有余了。 问题答案: 因为工作方式是这样的: 所以如果你给i它分配任何东西都不会影响。 解决方案是您所建议的,或者遍历索引: 或使用:

  • 图册播放像素决定了图册播放时的大小,可通过设置自定义改变大小。图册默认设置为自适应,会根据屏幕大小自动调整。 图册编辑页,右侧图册设置区,有图册大小设置选项。 勾选自适应,则根据播放环境自适应播放像素。也可以选择16:9的布局大小。 选择固定宽度,可设置固定的像素。同时,可选择实际大小和按宽度铺满两种显示方式(这是针对编辑区图册的显示设置)。

  • 我正在上传一个改型多部分API的图像。我在邮递员中取得了成功,但在代码中出现了以下错误: 响应{protocol=http/1.1,code=422,message=不可处理实体,url=http://upload-snack.13.251.251.232.nip.io/upload} 邮递员: null

  • 关于图像 虽然存在很多种图形文件格式,但网页中通常使用的只有三种,即 GIF、JPEG 和 PNG。GIF 和 JPEG 文件格式的支持情况最好,大多数浏览器都可以查看它们。 GIF(图形交换格式) GIF 文件最多使用 256 种颜色,最适合显示色调不连续或具有大面积单一颜色的图像,例如导航条、按钮、图标、徽标或其它具有统一色彩和色调的图像。 JPEG(联合图像专家组) JPEG 文件格式是用于