Preload approx. 10 images (8Mpix) in Java

I want to preload (load into memory) about 10 jpg images (size 3264px x 2448px). Each image file size is ~ 3 MB. I tried loading them into ArrayList from BufferedImage but I am getting OutOfMemoryError Exception (Java heap space). How to deal with this?

+3


source to share


3 answers


.. any possibility to save the image in a compressed form?

Load them as byte arrays of course and keep a reference to each array (3 Meg). Since you require every actual image, print it before the image by wrapping it in ByteArrayInputStream

and use that as the source for ImageIO.read(InputStream)

.



This will be approximately 30 megabytes for 10 byte[]

and 32 1 megabytes for each realized image.

  • AFAIU JPEG images cannot be transparent, so an image with 32 megabytes ARGB will be 24 megabytes in RGB quality.
+1


source


Each image file size is ~ 3 MB. I tried loading them into ArrayList BufferedImage, but I get OutOfMemoryError Exception (Java heap space). How to deal with this?

Each compressed image is 3MB in size. As you wrote in your name, 3264 * 2448 is 7,990,272 pixels (about 8 megapixels). Using shared ARGB, 32 bits per pixel or 32 MB per image.



If you want to preload these 10 images without compression (like ten BufferedImage

), you will need 320MB of memory for just these 10 images.

So, you need to run a Java application with a lot of memory.

+2


source


Just to keep an eye out, if you are absolutely sure that the best solution to your problem is to keep your images in memory, you can tweak the java heap size using -Xmx (maximum heap size) and possibly -Xmn (initial heap size), which are passed when JVM startup (java or javaw command). For your problem, maybe 512 megs would be good (-Xmx512m). The default maximum size is 64 megabytes, so you're running out of memory. For more information see http://docs.oracle.com/javase/1.3/docs/tooldocs/solaris/java.html

Having said that, while 320MB is not an outrageous amount of storage these days for multiple gigabyte computers, it certainly isn't insignificant. Unless you're doing something that requires very fast rendering, such as animation, I would think that leaving images as files would be fine in many cases.

And, a compromise solution was suggested above. Casting your image files to BufferedImages means you need 320MB. But, if you store the contents of the file itself as a byte, you only need 30MB. For this

a) Get the file size using the length method of the File object b) Allocate the byte [] array up to this size c) Use the FileInputStream read method to read the file into an array

Then when you want to convert your byte array to BufferedImage:

a) Use ByteArrayInputStream to convert byte array to InputStream b) Use ImageIo.read to convert InputStream to BufferedImage

However, I'm not sure if the compromise solution will be perceived by your users as much faster than just reading directly from the file. File IO is pretty fast these days.

0


source







All Articles