【问题标题】:BufferedImage slows down performanceBufferedImage 会降低性能
【发布时间】:2020-07-07 13:05:31
【问题描述】:

我正在开发一款游戏,没什么大不了的,只是为了好玩。
我写了一个类'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 只是两个 Vector2i

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

我尝试通过这样做(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 FPS。 我不知道有什么区别,我以前使用“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;
    }

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

我做错了什么?

【问题讨论】:

标签: java bufferedimage


【解决方案1】:

我的猜测是问题出在您的ImageBuilder 访问数据缓冲区的后备数据数组:

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

这样做可能(将)毁掉这张图片被硬件加速的机会。这是记录在案的行为,来自getData() API doc:

请注意,调用此方法可能会导致此 DataBuffer 对象与某些实现使用的性能优化(例如在视频内存中缓存关联的图像)不兼容。

您可能很容易解决这个问题,方法是在您的图片中使用临时图像,并从 build() 方法返回临时图像的副本,该副本尚未被“篡改”。

为了获得最佳性能,始终使用兼容的图像(如createCompatibleImage() 中的@VGR 在 cmets 中提到的)也是一个好主意。这应该可以确保您拥有尽可能快的硬件 blit。

【讨论】:

  • 我刚刚更改了 build() 使其返回图像的副本,现在效果很好,谢谢
猜你喜欢
  • 2016-02-25
  • 2015-07-01
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 2021-12-05
  • 1970-01-01
  • 2014-12-25
相关资源
最近更新 更多