I'm trying to create PDImageXObject from huge JPEG file (20 000 x 20 000 pixels [24-bit color])
Methods:
Creates ByteArrayInputStream
object and allocates more than 1GB of RAM, which causes Exception
java.lang.OutOfMemoryError: Java heap space
at java.io.ByteArrayOutputStream.<init>(ByteArrayOutputStream.java:77) ~[?:1.8.0_211]
Exception in line:
buf = new byte[size];
I know that the number of bytes for image processing =
W * H * color bits \ 9
;
That's why I don't want to load all file bytes at a time.
I've tried to set maximum heap size to -Xmx2G
but it isn't enough.
I've also tried to use methods
LosslessFactory.createFromImage(...),
JPEGFactory.createFromImage(...) , but they has the same problem
Is there any way to create PDImageXObject from InputStream (f.e. from FileInputStream), without creating BufferedImage or byte arrays ?
Spawn a thread to run a command-line utility (e.g. ImageMagick) which will reduce the size of the image to what will fit within the space on the page which you have allotted for the image.
Then load that reduced-size image.
You don't need a higher resolution image or bigger-size image than what will fit on the page.
There are also several java libraries which will do that for you without the considerable process-spawning overhead. See this Baeldung article for a quick rundown on the more popular ways to do so: Baeldung: How can I resize an image using Java?.
Of course, you'll have to experiment to see how much main memory each library uses.