JavaFX加载图像内存问题

JavaFX load image memory problems

当我在 JavaFX 中加载一个 15Mb 的图像时,它需要大约 250Mb 的 RAM!

Image imageColored = new Image("file:C:\Users\user\Desktop\portret.jpg");
ImageViewResizable imageView = new ImageViewResizable(imageColored);

并且复制它需要 10 秒,并将 RAM 使用量增加到 1Gb。

WritableImage imageBlack;

int width = (int) imageColored.getWidth();
int height = (int) imageColored.getHeight();

//make img black and white;
imageBlack = new WritableImage(width, height);
PixelReader pixelReader = imageColored.getPixelReader();
PixelWriter pixelWriter = imageBlack.getPixelWriter();

for (int x = 0; x < width; x++)
    for (int y = 0; y < height; y++) {
        Color color = pixelReader.getColor(x, y);
        double grey = (color.getBlue() + color.getGreen() + color.getRed()) / 3;
        pixelWriter.setColor(x, y, new Color(grey, grey, grey, color.getOpacity()));
    }

如何减少 RAM 使用并有效地复制图像?

这是预期的行为,已经在 J​​avaFX 错误系统中进行了讨论。为了克服这个问题,您需要在 Image() 中提供图像应缩放到的尺寸 构造函数。

根据 JavaFX 首席开发人员 Kevin Rushforth 的评论之一:

The png image is encoded in a way that it needs to be decoded before it can be used or displayed. When you construct an Image, it has to create that buffer with W*H pixels. Each pixel takes up 4 bytes in memory. As specified the default Image constructor takes the width and height specified in the file as the width and height of an image. This is a 5000*5000 image meaning 25,000,000 pixels. At 4 bytes each, that takes 100 Mbytes in memory. The only way to reduce the memory is to scale the image on the way in by specifying a smaller width and height to which the image is scaled.

虽然他说的是 PNG,但是用 W*H 创建缓冲区对于 JPEG 图像来说应该没有太大区别。

欲了解更多信息,请访问 - Huge memory consumption when loading a large Image