OP'nin üç sorusunu gerçekten ele almayan birçok cevap görebiliyorum.
1) Performansla ilgili bir kelime: bayt dizileri, ekran bağdaştırıcılarınızın geçerli çözünürlüğü ve renk derinliği ile eşleşen tam bir piksel bayt sırasını kullanmadıkça muhtemelen verimsizdir.
En iyi çizim performansını elde etmek için görüntünüzü mevcut grafik yapılandırmanıza karşılık gelen bir türle oluşturulan bir BufferedImage'a dönüştürmeniz yeterlidir. Https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html adresindeki createCompatibleImage sayfasına bakın.
Bu görüntüler otomatik olarak (bu Java 6 beri Swing standarttır) herhangi bir programlama çaba olmadan birkaç kez çizerek sonra ekran kartı belleğine önbelleğe edilecek ve dolayısıyla gerçek çizim zamanını önemsiz miktarda alacak - eğer görüntüyü değişmedi .
Görüntünün değiştirilmesi, ana bellek ile GPU belleği arasında ek bir bellek aktarımı ile birlikte gelir - bu yavaştır. Bu nedenle, görüntüyü BufferedImage'a "yeniden çizmekten" kaçının, getPixel ve setPixel'i hiçbir şekilde yapmaktan kaçının.
Örneğin, bir oyun geliştiriyorsanız, tüm oyun aktörlerini bir BufferedImage'a ve ardından bir JPanel'e çizmek yerine, tüm aktörleri daha küçük BufferedImages olarak yüklemek ve bunları JPanel kodunuzda tek tek çizmek çok daha hızlıdır. uygun konumları - bu şekilde, ana bellek ile GPU belleği arasında, önbelleğe alınacak görüntülerin ilk aktarımı dışında ek veri aktarımı olmaz.
ImageIcon, bufferedImage'ı kaputun altında kullanacaktır - ancak temel olarak bir BufferedImage'ı uygun grafik moduna atamak anahtardır ve bunu doğru yapmak için hiçbir çaba yoktur.
2) Bunu yapmanın genel yolu, JPanel'in geçersiz bir paintComponent yöntemine bir BufferedImage çizmektir. Java, GPU belleğinde önbelleğe alınan VolatileImages'ı kontrol eden tampon zincirler gibi iyi miktarda ek güzellikleri desteklese de, Java 6'nın tüm GPU hızlandırması ayrıntılarını göstermeden makul bir şekilde iyi bir iş çıkardığı için bunlardan herhangi birine gerek yoktur.
GPU hızlandırmanın yarı saydam görüntüleri genişletme gibi belirli işlemler için çalışmayabileceğini unutmayın.
3) Eklemeyin. Sadece yukarıda belirtildiği gibi boyayın:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
"Ekleme", resim mizanpajın bir parçasıysa mantıklıdır. Buna JPanel'i dolduran bir arka plan veya ön plan görüntüsü olarak ihtiyacınız varsa, sadece paintComponent öğesini çizin. Görüntünüzü gösterebilecek genel bir Swing bileşenini demlemeyi tercih ediyorsanız, aynı hikaye (bir JComponent kullanabilir ve paintComponent yöntemini geçersiz kılabilirsiniz) - ve bunu GUI bileşenleri düzeninize ekleyebilirsiniz .
4) Diziyi bir Bufferedimage'e dönüştürme
Bayt dizilerinizi PNG'ye dönüştürmek, sonra yüklemek oldukça kaynak yoğundur. Daha iyi bir yol, mevcut bayt dizinizi BufferedImage'a dönüştürmektir.
Bunun için: döngüler ve kopya pikseller için kullanmayın . Bu çok çok yavaş. Yerine:
- BufferedImage'ın tercih edilen bayt yapısını öğrenin (günümüzde piksel başına 4 bayt olan RGB veya RGBA'yı kabul etmek güvenlidir)
- tarama çizgisini öğrenin ve kullanımdaki taramayı öğrenin (örn. 142 piksel genişliğinde bir görüntünüz olabilir - ancak gerçek hayatta 256 piksel genişliğinde bayt dizisi olarak depolanacak ve kullanılmayan pikselleri GPU donanımı tarafından maskelemek daha hızlıdır. )
- daha sonra bu ilkelere göre bir dizi oluşturduğunuzda, BufferedImage'ın setRGB dizi yöntemi dizinizi BufferedImage'a kopyalayabilir.
MemoryImageSource
bunları JPEG veya PNG biçimine dönüştürmekten ve daha sonraImageIO
çoğu cevabın önerdiği şekilde okumaktan daha verimli olabilir . Bir alabilirImage
bir gelenMemoryImageSource
kullanarak görüntü verileri ile inşacreateImage
cevapların birinde söylediği gibi, ve ekran.