2

私は多くの画像のカスタム検索を含むプログラムを書いています。ユーザーが検索条件を入力すると、対応する画像がキャッシュまたはサーバーから取得されます。対応する画像へのリンクを表示するJTableがあります。ユーザーがリンクをクリックすると、画像がJPanelに表示されます。リンクをクリックするとハードドライブから画像を読み取ることができますが、思ったほど速くはありません。ロードには数秒かかります。BufferedImagesの配列を作成しようとしましたが、検索で多くの結果が返される場合は、問題が発生します。リンクをクリックしたときに画像をより速く表示するための最良の方法は何でしょうか。

これが私が画像を取得する方法です...

Public void getFile(String fileName){
File file = new File("./cache/"+fileName);
    boolean exists = file.exists();

    BufferedImage returnImage =null;
    if(exists){
        try {

            returnImage = ImageIO.read(file);
            System.out.println("Found In Cache!");
        } catch (IOException|IndexOutOfBoundsException e) {
            try {
                if(fileName != null){
                returnImage = downloadImage(fileName);
                System.out.println("Found ON Server :(");
                }
            } catch (IOException |IndexOutOfBoundsException ex) {
                // TODO Auto-generated catch block
                ex.printStackTrace();
            }
        }
    }else{
        try {
            if(fileName != null){
            returnImage = downloadImage(fileName);
            System.out.println("Found ON Server :(");
            }
        } catch (IOException |IndexOutOfBoundsException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    return returnImage; 

}
}

そして、これは私がそれらを配列に入れるところです...

BufferedImage[] images = new BufferedImage[numOfSearchResults];

for(SearchResult r: results){
     images[i] = imageCache.getFile(r.imageName);
}

基本的に、私は、画像をプリロードするための最良の方法は何であるかを考えています。前もって感謝します

4

4 に答える 4

3

画像が本当に本当に大きい(10メガピクセル以上)場合を除いて、ディスクから画像をロードするのに数秒かかるのは不合理に聞こえます。まず、時間が実際に費やされている場所を特定します。

キャッシュの場合、java.lang.ref.SoftReferenceを使用してロードした各画像への参照を保持できます。これにより、OOMを実行する前に画像をガベージコレクションできます。本当に避けられない場合は、メモリ内にSoftReferencesを備えた第1レベルの多層キャッシュシステムを使用し、サーバーベースのイメージの場合は追加のオンディスクキャッシュを使用します。イメージを探すときは、最初にメモリ内キャッシュがチェックされ、そこに何も見つからない場合はディスクキャッシュがチェックされ、それでも見つからない場合は通常の方法でイメージがロードされます。

于 2012-07-25T16:24:13.280 に答える
2

すべて/多すぎる画像をロードしないでください。現在のインデックスの前に結合画像をロードし、現在のインデックスの後に結合画像をロードしてください。

メインの実行スレッドをブロックしない別のスレッドとしてイメージローダーを実装し、ユーザーが現在ロードされているイメージを見ているときに追加のイメージをロードします。

于 2012-07-25T16:16:01.030 に答える
0

すべての画像に対してInputStreamを開き、ユーザーがクリックしていない画像を閉じて、必要な画像だけを使用することができます。

そうすれば、すべての画像をバッファリングする必要はありませんが、ユーザーがクリックしたときにすでに「到達可能」になっています。

しかし、@ Robinが正しくコメントしているので、平均的なサイズの画像をロードするのにそれほど時間はかからないはずです。

それでパフォーマンスが大幅に向上するかどうかはわかりませんが、状況によっては可能です。

于 2012-07-25T16:22:24.100 に答える
0

フルサイズの画像が必要ない場合は、メモリの量を減らすために、読み込み時に画像を縮小します。メモリにロードされた画像は圧縮されなくなったことを覚えておく必要があります。

ソース画像を制御できる場合は、サムネイルを生成して読み込みを高速化することを検討します。200x200のサムネイルを使用しており、SMBベースの共有でも、読み込みに1秒もかかりません。

于 2012-07-25T16:25:47.980 に答える