Riesco a vedere molte risposte, non rispondendo realmente alle tre domande del PO.
1) Una parola sulle prestazioni: gli array di byte sono probabilmente inefficienti a meno che non sia possibile utilizzare un esatto ordinamento di byte di pixel che corrisponda alla risoluzione corrente e alla profondità del colore degli adattatori del display.
Per ottenere le migliori prestazioni di disegno, è sufficiente convertire l'immagine in un'immagine bufferizzata che viene generata con un tipo corrispondente alla configurazione grafica corrente. Vedi createCompatibleImage su https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html
Queste immagini verranno automaticamente memorizzate nella memoria della scheda video dopo essere state disegnate alcune volte senza alcuno sforzo di programmazione (questo è standard in Swing da Java 6), e quindi il disegno effettivo richiederà un tempo trascurabile, se non si modifica l'immagine .
La modifica dell'immagine comporterà un ulteriore trasferimento di memoria tra la memoria principale e la memoria GPU, che è lento. Evita quindi di "ridisegnare" l'immagine in un'immagine bufferizzata, quindi evita di ottenere getPixel e setPixel in alcun modo.
Ad esempio, se stai sviluppando un gioco, invece di attirare tutti gli attori del gioco su un'immagine bufferizzata e quindi su JPanel, è molto più veloce caricare tutti gli attori come immagini bufferizzate più piccole e disegnarli uno a uno nel codice JPanel in la loro posizione corretta - in questo modo non vi è alcun trasferimento di dati aggiuntivo tra la memoria principale e la memoria GPU tranne il trasferimento iniziale delle immagini per la memorizzazione nella cache.
ImageIcon utilizzerà una BufferedImage sotto il cofano, ma fondamentalmente l'allocazione di una BufferedImage con la corretta modalità grafica è la chiave, e non c'è nessuno sforzo per farlo bene.
2) Il solito modo di fare questo è di disegnare un'immagine tamponata con un metodo di vernice sovrascritta Componente di JPanel. Sebbene Java supporti una buona quantità di extra aggiuntivi come catene di buffer che controllano VolatileImages memorizzati nella cache della memoria GPU, non è necessario utilizzare nessuno di questi dal momento che Java 6 fa un lavoro ragionevolmente buono senza esporre tutti questi dettagli dell'accelerazione GPU.
Si noti che l'accelerazione GPU potrebbe non funzionare per alcune operazioni, come lo stiramento di immagini traslucide.
3) Non aggiungere. Dipingi semplicemente come indicato sopra:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
"Aggiunta" ha senso se l'immagine fa parte del layout. Se hai bisogno di questo come immagine di sfondo o di primo piano che riempie JPanel, disegna semplicemente paintComponent. Se si preferisce birra una componente Swing generica che può mostrare la vostra immagine, allora è la stessa storia (si può utilizzare un JComponent e ignorare il suo metodo paintComponent) - e quindi aggiungere questo al layout dei componenti GUI.
4) Come convertire l'array in un'immagine bufferizzata
La conversione delle matrici di byte in PNG, quindi il caricamento richiede molta risorse. Un modo migliore è convertire l'array di byte esistente in una BufferedImage.
Per questo: non utilizzare per loop e copiare pixel. È molto lento. Anziché:
- apprendere la struttura di byte preferita di BufferedImage (al giorno d'oggi è sicuro assumere RGB o RGBA, che è di 4 byte per pixel)
- apprendi la linea di scansione e la scansione in uso (ad esempio potresti avere un'immagine larga 142 pixel - ma nella vita reale che verrà memorizzata come matrice di byte larga 256 pixel poiché è più veloce elaborarla e mascherare i pixel non utilizzati dall'hardware GPU )
- quindi, una volta creato un array secondo questi principi, il metodo array setRGB di BufferedImage può copiare l'array su BufferedImage.
MemoryImageSource
piuttosto che convertirli in formato JPEG o PNG e quindi leggereImageIO
come suggerisce la maggior parte delle risposte. È possibile ottenere unImage
da unMemoryImageSource
costruito con i dati delle immagini utilizzandocreateImage
e visualizzare come suggerito in una delle risposte.