Reputation: 327
When I load an 15Mb image in JavaFX, it takes like 250Mb of RAM!
Image imageColored = new Image("file:C:\\Users\\user\\Desktop\\portret.jpg");
ImageViewResizable imageView = new ImageViewResizable(imageColored);
And copying it takes 10 seconds and increases RAM usage up to 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()));
}
How can I decrease RAM usage and copy image effectively?
Upvotes: 1
Views: 1963
Reputation: 36802
This is expected behaviour and has already been discussed in the JavaFX bug system. To overcome this you need to provide the size of the image to which the image should be scaled, in the Image()
constructor.
According to one of the comments by a JavaFX lead developer 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.
Although, he talks about PNG, creating buffer with W*H must not be very different for JPEG images.
For more information visit - Huge memory consumption when loading a large Image
Upvotes: 4