OPの3つの質問に実際に対処するのではなく、多くの答えを見ることができます。
1)パフォーマンスについて一言:ディスプレイアダプターの現在の解像度と色深度に一致する正確なピクセルバイト順序を使用できない場合、バイト配列はおそらく非効率です。
最高の描画パフォーマンスを実現するには、画像を現在のグラフィックス構成に対応するタイプで生成されたBufferedImageに変換するだけです。https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.htmlで createCompatibleImageを参照してください
これらの画像は、何もプログラミングせずに数回描画した後、ディスプレイカードのメモリに自動的にキャッシュされます(これはJava 6以降のSwingの標準です)。したがって、実際の描画にかかる時間はごくわずかです。です画像を変更しなかった。
イメージを変更すると、メインメモリとGPUメモリ間のメモリ転送が追加されますが、これは低速です。したがって、画像をBufferedImageに「再描画」することは避け、getPixelとsetPixelは絶対に行わないでください。
たとえば、ゲームを開発している場合、すべてのゲームアクターをBufferedImageに描画してからJPanelに描画するのではなく、すべてのアクターを小さいBufferedImagesとしてロードして、JPanelコードで1つずつ描画する方がはるかに高速です。それらの適切な位置-この方法では、キャッシュ用の画像の初期転送を除いて、メインメモリとGPUメモリの間で追加のデータ転送は行われません。
ImageIconは内部でBufferedImageを使用しますが、基本的には適切なグラフィックスモードでBufferedImageを割り当てることが重要であり、これを正しく行うための努力はありません。
2)これを行う通常の方法は、JPanelのオーバーライドされたpaintComponentメソッドでBufferedImageを描画することです。Javaは、GPUメモリにキャッシュされたVolatileImagesを制御するバッファーチェーンなど、追加の優れた機能を多数サポートしていますが、GPUアクセラレーションのこれらの詳細のすべてを公開することなくかなり良い仕事をするJava 6以降、これらを使用する必要はありません。
GPUアクセラレーションは、半透明画像のストレッチなどの特定の操作では機能しない場合があることに注意してください。
3)追加しないでください。上記のように塗ってください:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
「追加」は、画像がレイアウトの一部である場合に意味があります。JPanelを塗りつぶす背景または前景の画像としてこれが必要な場合は、paintComponentで描画してください。画像を表示できる汎用のSwingコンポーネントを作成したい場合は、同じストーリーです(JComponentを使用してpaintComponentメソッドをオーバーライドできます)。これをGUIコンポーネントのレイアウトに追加します。
4)配列をBufferedimageに変換する方法
バイト配列をPNGに変換してからロードすると、かなりのリソースを消費します。より良い方法は、既存のバイト配列をBufferedImageに変換することです。
そのため:forループを使用せず、ピクセルをコピーします。それは非常に遅いです。代わりに:
- BufferedImageの優先バイト構造を学習します(現在、ピクセルごとに4バイトであるRGBまたはRGBAを想定しても安全です)。
- 使用中のスキャンラインとスキャンサイズを学習します(たとえば、142ピクセル幅の画像があるかもしれませんが、実際には256ピクセル幅のバイト配列として格納されます。これは、GPUハードウェアで処理して未使用のピクセルをマスクする方が速いためです。 )
- 次に、これらの原則に従って配列を作成したら、BufferedImageのsetRGB配列メソッドで配列をBufferedImageにコピーできます。
MemoryImageSource
、を使用してJPEGまたはPNG形式に変換しImageIO
、ほとんどの回答が示唆するように読み取る方が効率的です。を使用して画像データで構成されたImage
からを取得し、回答の1つで提案されているように表示できます。MemoryImageSource
createImage