Ich kann viele Antworten sehen, die die drei Fragen des OP nicht wirklich ansprechen.
1) Ein Wort zur Leistung: Byte-Arrays sind wahrscheinlich ineffizient, es sei denn, Sie können eine genaue Pixel-Byte-Reihenfolge verwenden, die der aktuellen Auflösung und Farbtiefe Ihres Displayadapters entspricht.
Um die beste Zeichenleistung zu erzielen, konvertieren Sie Ihr Bild einfach in ein BufferedImage, das mit einem Typ generiert wird, der Ihrer aktuellen Grafikkonfiguration entspricht. Siehe createCompatibleImage unter https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html
Diese Bilder werden nach mehrmaligem Zeichnen ohne Programmieraufwand automatisch im Speicher der Grafikkarte zwischengespeichert (dies ist in Swing seit Java 6 Standard). Daher dauert das eigentliche Zeichnen vernachlässigbar lange - wenn Sie das Bild nicht geändert haben .
Das Ändern des Bildes führt zu einer zusätzlichen Speicherübertragung zwischen Hauptspeicher und GPU-Speicher - was langsam ist. Vermeiden Sie das "Neuzeichnen" des Bildes in ein BufferedImage. Vermeiden Sie daher auf jeden Fall getPixel und setPixel.
Wenn Sie beispielsweise ein Spiel entwickeln, anstatt alle Spielakteure in ein BufferedImage und dann in ein JPanel zu zeichnen, ist es viel schneller, alle Akteure als kleinere BufferedImages zu laden und sie einzeln in Ihrem JPanel-Code unter zu zeichnen ihre richtige Position - auf diese Weise gibt es keine zusätzliche Datenübertragung zwischen dem Hauptspeicher und dem GPU-Speicher außer der anfänglichen Übertragung der Bilder zum Zwischenspeichern.
ImageIcon verwendet ein BufferedImage unter der Haube - aber im Grunde ist es der Schlüssel, ein BufferedImage mit dem richtigen Grafikmodus zuzuweisen , und es gibt keine Anstrengungen, dies richtig zu machen.
2) Der übliche Weg, dies zu tun, besteht darin, ein BufferedImage in einer überschriebenen paintComponent-Methode des JPanel zu zeichnen. Obwohl Java eine große Anzahl zusätzlicher Extras unterstützt, wie z. B. Pufferketten, die im GPU-Speicher zwischengespeicherte VolatileImages steuern, müssen diese nicht verwendet werden, da Java 6 eine einigermaßen gute Arbeit leistet, ohne all diese Details der GPU-Beschleunigung offenzulegen.
Beachten Sie, dass die GPU-Beschleunigung bei bestimmten Vorgängen möglicherweise nicht funktioniert, z. B. beim Strecken durchscheinender Bilder.
3) Nicht hinzufügen. Malen Sie es einfach wie oben erwähnt:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
"Hinzufügen" ist sinnvoll, wenn das Bild Teil des Layouts ist. Wenn Sie dies als Hintergrund- oder Vordergrundbild benötigen, das das JPanel ausfüllt, zeichnen Sie einfach paintComponent ein. Wenn Sie es vorziehen, eine generische Swing-Komponente zu brauen, die Ihr Bild anzeigen kann, ist es dieselbe Geschichte (Sie können eine JComponent verwenden und ihre paintComponent-Methode überschreiben) - und diese dann Ihrem Layout der GUI-Komponenten hinzufügen .
4) So konvertieren Sie das Array in ein Pufferbild
Das Konvertieren Ihrer Byte-Arrays in PNG und das anschließende Laden ist sehr ressourcenintensiv. Eine bessere Möglichkeit besteht darin, Ihr vorhandenes Byte-Array in ein BufferedImage zu konvertieren.
Dafür: Nicht für Schleifen verwenden und Pixel kopieren. Das ist sehr sehr langsam. Stattdessen:
- Lernen Sie die bevorzugte Bytestruktur des BufferedImage kennen (heutzutage ist es sicher, RGB oder RGBA anzunehmen, was 4 Bytes pro Pixel entspricht).
- Lernen Sie die verwendete Scanlinie und die gescannte Größe (z. B. haben Sie möglicherweise ein Bild mit einer Breite von 142 Pixel - aber im wirklichen Leben wird dieses als 256 Pixel breites Byte-Array gespeichert, da es schneller verarbeitet werden kann und die nicht verwendeten Pixel von der GPU-Hardware maskiert werden )
- Sobald Sie ein Array nach diesen Prinzipien erstellt haben, kann die Array-Methode setRGB des BufferedImage Ihr Array in das BufferedImage kopieren.
MemoryImageSource
als sie in das JPEG- oder PNG-Format zu konvertieren und dann mitImageIO
den meisten Antworten zu lesen . Sie können eineImage
aus einemMemoryImageSource
mit Ihren Bilddaten erstellte Daten erhalten, indem Sie diese verwendencreateImage
und anzeigen, wie in einer der Antworten vorgeschlagen.