5

特定のディレクトリにある画像のサムネイルを表示する必要があります。画像を画像コンポーネントにロードする前に、TFileStream を使用して画像ファイルを読み取ります。その後、ビットマップはサムネイル サイズにサイズ変更され、TScrollBox の TImage コンポーネントに割り当てられます。

正常に動作しているように見えますが、画像が大きくなるとかなり遅くなります。

ディスクから (イメージ) ファイルをロードしてサイズを変更するより高速な方法はありますか?

ありがとう、ピーター

4

6 に答える 6

5

可能な限り高速になるようにこれを設計する試みで、skamradt による回答を補足します。このためには、

  • I/O を最適化する
  • 複数のスレッドを使用して複数の CPU コアを利用し、ファイルの読み取り (または書き込み) 中に単一の CPU コアでも動作させ続ける

複数のスレッドを使用するということは、サイズ変更に VCL クラスを使用しても機能しないことを意味します。VCL はスレッドセーフではなく、その周りのすべてのハックは適切にスケーリングされないためです。efg の Computer Labには、画像処理コードのリンクがあります。

複数のスレッドを使用する場合は、同時に複数の I/O 操作を行わないようにすることが重要です。サムネイル画像をファイルに書き戻すことを選択した場合、ファイルの読み取りを開始したら完全に読み取り、ファイルの書き込みを開始したら完全に書き込む必要があります。両方の操作をインターリーブすると、ハード ディスク ヘッドの多くのシーク操作が発生する可能性があるため、I/O が停止します。

最良の結果を得るには、アプリケーションのメイン (GUI) スレッドでファイルの読み取り (および書き込み) も行わないでください。これは、次の設計を示唆しています。

  • 1 つのスレッドにファイルを TGraphic オブジェクトに読み込ませ、これらをスレッドセーフ リストに入れます。
  • スレッド プールを元のサイズのファイルのリストで待機させ、1 つのスレッドで 1 つの TGraphic オブジェクトを処理し、それを別の TGraphic オブジェクトにサイズ変更し、これを別のスレッド セーフ リストに追加します。
  • リストに追加されたサムネイル画像ごとに GUI スレッドに通知し、表示できるようにします。
  • サムネイルをファイルに書き込む場合は、読み取りスレッドでもこれを行います (説明については上記を参照してください)。

編集:

あなたの質問を読み直すと、おそらく 1 つの画像のサイズを変更するだけでよいことに気付きました。その場合、もちろん 1 つのバックグラウンド スレッドで十分です。とにかく、答えはそのままにしておきます。おそらく、いつか他の誰かに役立つでしょう。これは、私の最近のプロジェクトの 1 つから学んだことです。このプロジェクトでは、最終的なプログラムではもう少し速度が必要だったかもしれませんが、ピーク時にクアッド コア マシンの約 75% しか使用していませんでした。I/O を処理から切り離すことで、違いが生まれます。

于 2009-05-07T17:03:20.350 に答える
5

あまり。できることは、バックグラウンド スレッドでサイズを変更し、サイズ変更が完了するまで「プレース ホルダー」イメージを使用することです。次に、これらのサイズ変更された画像を、後で処理するためにある種のキャッシュ ファイルに保存します (Windows はこれを行い、現在のディレクトリでキャッシュの thumbs.db を呼び出します)。

スレッド アーキテクチャ自体にはいくつかのオプションがあります。すべての画像を処理する単一のスレッド、またはスレッドが単一の画像の処理方法しか知らないスレッド プール。AsyncCallsライブラリはさらに別の方法であり、物事をかなり単純に保つことができます

于 2009-05-07T16:30:48.090 に答える
4

Scale:=jsEighth (Delphi 7) で TJPEGImage をよく使用します。これは非常に高速です。これは、JPEG 圧縮解除が大量のデータをスキップして、幅と高さがわずか 8 分の 1 のビットマップを埋めることができるためです。

別のオプションは、シェルのメソッドを使用してサムネイルを抽出することです。これも非常に高速です

于 2009-05-07T17:32:29.877 に答える
1

私はビジョン ビジネスに携わっており、OpenGL を使用して画像を GPU にアップロードするだけです。(通常、1 秒あたり 20x 2048x2000x8bpp)、テクスチャあたりの bmp、ビデオカードのスケーリング (win32、Mike Lischke の opengl ヘッダー)

このような画像のアップロードには、正確なビデオカードに応じて 5 ~ 10 ミリ秒かかります (統合されておらず、nvidia 7300 シリーズ以降の場合。ごく最近の統合 GPU でも実行できる場合があります)。スケーリングと表示には 300us かかります。つまり、顧客はアプリに触れることなく、狂ったようにパンとズームを行うことができます。その上にオーバーレイ (以前は tmetafile でしたが、現在は独自の形式になっています) を描画します。

私の最大の写真は 4096x7000x8bpp で、30 ミリ秒未満で表示およびスケーリングされます。(GF8600)

このテクノロジーの制限は、最大テクスチャ サイズです。写真を複数のテクスチャに断片化することで解決できますが、ソフトウェアと一緒にシステムを提供しているので、まだ気にしていません。

(いくつかの典型的なサイズ:nv6x00シリーズ:2k * 2kですが、アップロードはGDI nv7x00シリーズ:4k * 4kと比較してほぼ損益分岐点です。私にとってはベースラインカードです。GF7300は20〜40ドルですnv8x00シリーズ:8k * 8k)

これはすべての人に当てはまるわけではないことに注意してください。しかし、ハードウェアの制限を指定する幸運な状況にある場合は、うまくいくかもしれません。主な問題は、Thinkpad のようなラップトップであり、その GPU は平均的なラップトップよりも古く、多くの場合、デスクトップよりも世代が遅れています。

私が DirectX よりも OpenGL を選択したのは、時間がより静的であり、ゲームに関連しない例を見つけやすいためです。

于 2009-05-07T19:24:14.740 に答える
0

Graphics32 ライブラリを調べてみてください。描画が非常に得意で、ビットマップとうまく連携します。それらはスレッドセーフであり、良い例があり、完全に無料です。

于 2009-05-13T11:08:54.720 に答える
0

ウィンドウの容量を活用してサムネイルを作成します。画像を含むフォルダに Thumbs.db ファイルが隠されていることを覚えていますか?

この機能のようなものを VB で実装しました。私のソフトウェアは、約 10 秒で 100 個のファイル (混合サイズ) のサムネイルを作成できます。

ただし、Delphi に変換することはできません。

于 2009-05-08T14:23:16.740 に答える