有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java BuffereImage会降低性能

我在做一个游戏,没什么大不了的,只是为了好玩
我写了一个“ImageBuilder”类来帮助创建一些图像
除了一件事,一切都很好
我初始化一个变量,如下所示:

// other stuff
m_tile = new ImageBuilder(TILE_SIZE, TILE_SIZE, BufferedImage.TYPE_INT_RGB).paint(0xff069dee).paintBorder(0xff4c4a4a, 1).build();
// other stuff

然后,在渲染方法中,我有:

for (int x = 0; x < 16; x++) {
    for (int y = 0; y < 16; y++) {
         g.drawImage(m_tile, x * (TILE_SIZE + m_padding.x) + m_margin.x, y * (TILE_SIZE + m_padding.y) + m_margin.y, null);
    }
}

注意:m_padding和m_margin只是两个向量2i

这在屏幕上绘制了一个简单的16x16表,使用该图像,但游戏几乎冻结,我无法获得超过10帧的速度

我尝试在没有该类的情况下创建图像,方法是(TILE_SIZE=32):

m_tile = new BufferedImage(TILE_SIZE, TILE_SIZE, BufferedImage.TYPE_INT_RGB);

for (int x = 0; x < TILE_SIZE; x++) {
    for (int y = 0; y < TILE_SIZE; y++) {
        if (x == 0 || y == 0 || x + 1 == TILE_SIZE || y + 1 == TILE_SIZE)
             m_tile.setRGB(x, y, 0x4c4a4a);
        else
             m_tile.setRGB(x, y, 0x069dee);
    }
}

这一次,我的速度是每秒60帧。 我搞不清楚两者之间的区别,我以前用“ImageBuilder”创建图像,一切都很好,但这次不行

ImageBuilder类:

    // Constructor
    public ImageBuilder(int width, int height, int imageType) {
        this.m_width = width;
        this.m_height = height;
        this.m_image = new BufferedImage(m_width, m_height, imageType);
        this.m_pixels = ((DataBufferInt) m_image.getRaster().getDataBuffer()).getData();
        this.m_image_type = imageType;
    }

    public ImageBuilder paint(int color) {
        for (int i = 0; i < m_pixels.length; i++) m_pixels[i] = color;
        return this;
    }

    public ImageBuilder paintBorder(int color, int stroke) {
        for (int x = 0; x < m_width; x++) {
            for (int y = 0; y < m_height; y++) {
                if (x < stroke || y < stroke || x + stroke >= m_width || y + stroke >= m_height) {
                    m_pixels[x + y * m_width] = color;
                }
            }
        }
        return this;
    }

    public BufferedImage build() {
        return m_image;
    }

还有其他方法,但我不调用它们,所以我认为没有必要编写它们

我做错了什么


共 (1) 个答案

  1. # 1 楼答案

    我猜问题在于ImageBuilder访问数据缓冲区的备份数据数组:

    this.m_pixels = ((DataBufferInt) m_image.getRaster().getDataBuffer()).getData();
    

    这样做,可能(将)破坏这个图像被硬件加速的机会。这是^{} API doc中记录的行为:

    Note that calling this method may cause this DataBuffer object to be incompatible with performance optimizations used by some implementations (such as caching an associated image in video memory).

    你可以很容易地绕过这个问题,在你的bilder中使用一个临时映像,并从build()方法返回一个没有被“篡改”的临时映像副本

    为了获得最佳性能,始终使用兼容的映像(如@VGR在评论中提到的createCompatibleImage())也是一个好主意。这将确保您拥有尽可能快的硬件故障