【问题标题】:Faster way to create large BufferedImages创建大型 BufferedImages 的更快方法
【发布时间】:2015-07-11 12:53:27
【问题描述】:

我正在寻找一种更快的方法来创建大型 (12291x12291) BufferedImages。我正在使用 Graphics2D g2d = image.createGraphics() 在其上绘图,将其保存到文件中,然后使用 g.drawImage(image, 0, 0, null);加载它。我正在保存文件,以便稍后加载特定图像。截至目前,创建图像大约需要 45 秒到 1 分钟。有什么方法可以更快地创建这些图像?

我正在创建其中两个图像。

public void drawTiles() {       
    Graphics2D g2d = tiles1.createGraphics();

    left = 0;
    top = 0;
    //The drawing takes around 10 to 20 seconds
    Colors c = new Colors();
    for (double[] row : data) {
        for (double d : row) {
            int v = (int) (20 - d / 500);
            if (v < 0) {
                v = 0;
            } else if (v > 20) {
                v = 20;
            }
            color = v;
            g2d.setColor(c.colors[color]);

            g2d.fillRect(left, top, sizeX, sizeY);
            left += sizeX;
            if (left == size * sizeX) {
                left = 0;
                top += sizeY;

            }
        }
    }     
    g2d.dispose();

    //The creation of the file takes little time for an image of this size
    try {
        File tiles1file = new File("path/to/map" + id + ".bmp");
        ImageIO.write(tiles1, "bmp", tiles1file);

    } catch (Exception ex) {
        ex.printStackTrace();
    }

    id++;
}

【问题讨论】:

  • 您确定“创建图像”是需要很长时间的部分吗?你能展示你的代码吗?
  • 与完全在内存中从头开始创建图像相比,压缩和解压缩 PNG(使用 DEFLATE)并不完全快。
  • 但是,试试 BMP 文件怎么样?它们是未压缩的,主要受磁盘速度(~100 MB/s)的限制。您的 12291×12291 图像大约需要 450 MB。
  • 我尝试使用创建 BMP 文件,但速度有所不同(大约需要 30 秒),但这么小的时间差异值得额外的空间吗?我可以做些什么来进一步加快速度吗?
  • 1.尝试将 g2d 上的 RenderingHints 设置为“性能”。 2. 交换行和列以匹配 BufferedImage 的 Java2D 内部坐标。 3. 重写你的代码,让 BufferedImages 永远不会大于 1M-Pixels(这大约是在 RAM 而不是 VRAM 中处理它们之后的限制)

标签: java bufferedimage


【解决方案1】:

我会将Colors c = new Colors(); 移到所有循环之外。每次创建和垃圾收集该对象都会减慢速度,至少在 JIT 发现它可以优化之前。

由于磁盘访问比计算慢得多,您可以尝试通过将质量设置为零来最大化 PNG 的压缩:

try (ImageOutputStream out = ImageIO.createImageOutputStream(tiles1file)) {
    ImageWriter writer = ImageIO.getImageWritersByFormatName("png").next();
    writer.setOutput(out);

    ImageWriteParam param = writer.getDefaultWriteParam();
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionQuality(0);

    writer.write(null, new IIOImage(tiles1, null, null), param);
}

【讨论】:

    猜你喜欢
    • 2015-07-30
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多