首页 > 解决方案 > 如何更快地处理 BufferedImage

问题描述

我正在制作一个基本的图像编辑器来提高我的图像处理技能。我有 12 个过滤器(目前)。 所有过滤器都有一个可点击的带有图像的 JLabel, 当所有过滤器都应用此功能时,我会更新所有过滤器的图像:

public static void buttonImagesUpdater(){
    for(int i = 0; i < effects.size(); i++){
        effects.get(i).getButton().setImage(new ImageIcon(effects.get(i).process(image)));
    }
}

所有过滤器都有这样的处理功能:

public BufferedImage process(BufferedImage base) {
    BufferedImage product = new BufferedImage(base.getWidth(), base.getHeight(), base.getType());
    for(int indisY = 0; indisY < base.getHeight(); indisY++){
        for(int indisX = 0; indisX < base.getWidth(); indisX++){
            Color currentColor = new Color(base.getRGB(indisX, indisY));
            int greyTone = 0;
            greyTone = (int) (currentColor.getRed()*0.315) +
                    (int) (currentColor.getGreen()*0.215) 
                    + (int) (currentColor.getBlue()*0.111);
            product.setRGB(indisX, indisY, new Color(greyTone,greyTone,greyTone).getRGB());

        }
    }
    return product;
}

程序运行得很慢。当我单击效果按钮时,当我使用 5000x3000 图像时,它会在 45 秒后完成。我该如何解决这个性能问题?

标签: javaimage-processingbufferedimage

解决方案


你可以试试这个,看看事情是否会加快一点。

  • 这使用来自 Image Raster 的 DataBuffer。
  • 并使用贴图保留以前转换的颜色。根据图像的类型,它可能会在一段时间内有所帮助。
  • 由于数据缓冲区支持各种类型,因此可以使用双精度数。

我还将您的值乘以 2 的幂,以将它们移动到正确的位置。Color 的 get* 方法返回的值介于 0 和 255 之间(含)。RGB 占用 int 的低 24 位(Alpha 在最左边的字节中)。

我看到的只是一张深色图像,但我用其他参数测试了它,我知道它有效。帐篷里的长杆似乎在读写图像。我正在使用6637 3787图像,并且可以在 12 秒内读取、更改和写入它。对于更高级的处理,您可能需要检查AffineTransformOp

    static Map<Color, Double> colorMap = new HashMap<>();

    public BufferedImage process(BufferedImage base) {
        DataBuffer db = base.getRaster().getDataBuffer();
        for (int i = 0; i < db.getSize(); i++) {
            Color currentColor = new Color(db.getElem(i));
            double greyTone = colorMap.computeIfAbsent(currentColor, v-> 
            currentColor.getRed() * .315 *256*256
                        + currentColor.getGreen() *.215 * 256
                            + currentColor.getBlue()*.115);

            db.setElemDouble(i, greyTone);

        }
        return base;    
    }

推荐阅读