Come altri hanno sottolineato, l'utilizzo di Java non è necessariamente la soluzione migliore qui.
Se stai per utilizzare Java, la soluzione migliore è che, supponendo che la memoria sia sufficientemente breve, in modo che non sia possibile leggere l'intero set di dati in memoria più volte e quindi scriverlo di nuovo, è necessario implementare RenderedImage
con una classe che leggerà i file PNG dal disco su richiesta. Se crei la tua nuova BufferedImage e poi provi a scriverlo, il writer PNG creerà una copia extra dei dati. Se crei la tua RenderedImage, puoi passarla a ImageIO.write(myImageSet,"png",myFileName)
. È possibile copiare le informazioni SampleModel
e ColorModel
dal primo PNG, si spera che siano tutte uguali.
Se fai finta che l'intera immagine è più tessere (una tessera immagine di origine per), quindi ImageIO.write
creerà un WritableRaster
che è la dimensione del l'intero set di dati di immagine, e richiederà l'implementazione di RenderedImage.copyData
a riempirlo con dati. Se hai abbastanza memoria, questa è una strada facile da percorrere (perché ottieni un enorme set di dati di destinazione e puoi semplicemente riversare tutti i dati dell'immagine su di essa - usando il metodo setRect(dx,dy,Raster)
- e poi non devi preoccuparti di nuovamente). Non ho provato per vedere se questo fa risparmiare memoria, ma mi sembra che dovrebbe.
In alternativa, se si pretende che l'intera immagine sia una singola tessera, ImageIO.write
chiederà quindi, utilizzando getTile(0,0)
, per il raster corrispondente a quell'intera immagine. Quindi devi creare il tuo Raster, che a sua volta ti fa creare il tuo DataBuffer. Quando ho provato questo approccio, l'utilizzo minimo della memoria che ha scritto correttamente un PNG RGB 15360x25600 era -Xmx1700M
(in Scala, per inciso), che è appena appena più di 4 byte per pixel di immagine scritta, quindi c'è poco overhead sopra un'immagine piena in memoria .
Il formato dei dati PNG non è uno che richiede l'intera immagine in memoria - funzionerebbe bene in blocchi - ma, purtroppo, l'implementazione predefinita del writer PNG presuppone che avrà l'intera matrice di pixel in memoria .
Vuoi un massiccio PNG? saranno 1536000x1536000 pixel? Devo dire che una libreria di immagini di base sarebbe un'opzione migliore qui. – kyndigs
Anche se c'è un modo per re-encoding, un'immagine molto grande ricodificata potrebbe potenzialmente comprimersi molto meglio, specialmente se le immagini sono simili. – Thilo
@kyndigs: più simile a 15360 x 25600 (per un arrangiamento 60 x 100) – Thilo