Domanda

Ho fatto questa domanda prima, ma ho voluto riformulare / chiarire alcuni punti ed espandere su di essa. Ho un pezzo di codice che trasforma un BufferedImage utilizzando un AffineTransform.

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage = op.filter(displayImage, null);

Questo codice funziona bene, ma che provoca un accumulo di memoria. In particolare, ogni volta che questo pezzo di codice viene chiamato più memoria viene immagazzinata. Ho provato l'altra forma di filtro pure.

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage2 = op.createCompatibleDestImage(displayImage, displayImage.getColorModel());
op.filter(displayImage, displayImage2);

Tuttavia, questo è molto molto più lento rispetto alla prima versione. Voglio che la velocità della prima versione, con l'utilizzo della memoria della seconda.

  1. Come posso pulire dopo la prima versione? In particolare, dove sono i BufferedImages intermedi memorizzati, e come posso eliminare?
  2. Perché è la seconda versione più lenta della prima? Cosa posso fare per accelerarlo?

Grazie per il vostro aiuto !!!

È stato utile?

Soluzione

Come va displayImage e ciò che è vero ColorModel usando?

Se è un IndexColorModel, che possono spiegare molto.

Il primo frammento di codice restituirà un BufferedImage utilizzando un DirectColorModel. Ciò richiederà 4 byte per pixel vs tipicamente 1 byte per pixel per un'immagine indicizzata. Quella 1:. Espansione 4 potrebbe essere la causa vostra condizione di memoria

Il secondo frammento di codice effettua una BufferedImage con lo stesso modello come origine. Quando ciò è un IndexColorModel e l'interpolazione non è NEAREST_NEIGHBOR, la chiamata filter() creerà un BufferedImage temporanea con un DirectColorModel. Userà che come destinazione del funzionamento del filtro, quindi requantize il buffer temporaneo e disegnare nella tua displayImage2. Così, il doppio dei bitblits.

Se si sta solo facendo una sola trasformata, direi andare con la seconda forma.

Se stai facendo operazioni multiple, allocare un paio di BufferedImages con un DirectColorModel. abbastanza grande da contenere l'immagine più grande. Disegna tu immagine di origine in uno di loro e di eseguire i filtri avanti e indietro tra di loro. Poi, quando hai finito, utilizzare un ColorConvertOp per requantize tornare a un'immagine indicizzata. In questo modo avete solo bisogno di convertire il colore una volta invece che su ogni chiamata filtro.

Altri suggerimenti

Sono d'accordo con il commento che se non stai ricevendo OutOfMemoryErrors, allora questa è una cosa normale e il GC raccoglierà le immagini ogni volta che lo ritenga opportuno. Ecco una prova di stupido ho fatto a volte quando ho avuto una preoccupazione: che mettere in loop in una funzione principale e guardare l'utilizzo della memoria in un profiler (dovrebbe fare un percorso a zig-zag-come o qualcosa del genere), ma non sempre in grado di completare con successo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top