2

私には問題があります: (そうでなければ私はここにいないでしょう ;)

「3D」モデルを表示する機能を持つアプリを作成しています。この部分は実際にはさまざまな角度から撮影された画像の集まりであり、ユーザーは「モデル」を「回転」させることができます。このアイデアはうまく機能していますが、問題は画像の読み込みにあります。

次の 2 つの方法があることがわかりました。

  1. すべての画像をメモリにロードし、正しい角度に切り替えるだけです。
  2. 必要に応じて画像をロードします。事前にいくつかロードできます。

ただし、これらには問題があります。

  1. 運が良ければ、画像は記憶に収まるでしょうが、そうではありません。それぞれ約 1.5 ~ 2 MB で、モデルごとに約 75 ~ 100 枚の画像があります。これにより、合計サイズは最小で約 115MB になります。
  2. 運が良ければ、ユーザーが「回転」するよりも画像が速く読み込まれますが、そうではありません。ユーザーは、まだロードされていないアングルに簡単に切り替えることができ、その結果、数秒間黒い画面が表示されます。

必要な画像をスタックに簡単に追加できるローダーを作成しました。ローダーは画像を 1 つずつロードします。ユーザーがかなりゆっくりとスクロールする場合、これは問題なく機能します。私のローダーは、終了時にメモリを解放する処理を行うため、ロードする画像の数に関係なく、メモリに保存する最大画像を指定している限り、通常、アプリはクラッシュしません。私のローダーは画像を非常に迅速にロードできますが、大きな画像をメモリにロードするにはまだ数ミリ秒 (~250ms) かかります。もちろん、ローダーは別のスレッドにあり、読み込みによって UI の応答が妨げられることはありません。そのため、ユーザーがすばやく前後にスワイプすると、実際には画像が表示されません。ロードとアンロードがすべて同時に機能して画像が表示されないためです:)

だから、私の問題: すべての画像をメモリにロードせずに、スムーズでユーザーに喜ばれる画像の回転を提供するにはどうすればよいですか?

4

3 に答える 3

4

必要のない解像度をロード (または保存) しないでください。ユーザーがズームする必要がある場合、メモリ不足のバイナリ イメージ ピラミッドは、必要なズーム レベルのみをロードできる安価な方法です。ユーザーが表示領域よりも大きな画像をパンする必要がある場合は、大きな画像を小さなタイルに分割し、必要なものだけを読み込むことができます。

さらに工夫を凝らしたい場合は、UI 対応のキャッシュ マネージャーを記述して、すぐに必要になる可能性があると思われるタイルをプリエンプティブに読み込み、すぐには必要ないと確信しているタイルにプリエンプション用のマークを付けることができます。

圧縮率が高いほど、より多くの画像データがメモリに収まり、読み込み時間が短縮されます。そのため、個々の画像圧縮に注意し、必要のない画質も読み込まないようにしてください。

特別な手段として、わずかに異なる角度からの画像は互いに似ているため、代わりに違いを表すことで時間とスペースを節約できる場合があります-ライトフィールド圧縮を調べてください。圧縮された形式から描画可能な特定のビットマップに変換する必要がありますが、圧縮によってデータセットをメモリに残すことができれば、速度が大幅に向上する可能性があります。

圧縮されたデータセットをメモリに収めることができない場合、ユーザーがすばやく前後にスワイプしてキャッシュを無効にできる可能性が高くなります。したがって、滑らかさが主な目標である場合は、回転率 (またはスワイプごとの回転範囲?) をデータ ローダーが追従できるものに制限することで、「UI ソリューション」を試すことができます。

于 2012-06-14T19:58:25.463 に答える
1

私の唯一の提案は、それらを効率的にロードすることです。ここで説明されている手法を使用していると仮定します

画像の解像度が画面よりも高い場合は、レンダリングする画像のサンプル サイズを計算して、フル サイズの画像ではなく、画面に収まる画像を読み込むことができます。すでにそれを行っている場合、私には、すでに効率的に行っているように思えます。おそらく、画像の読み込み中に何らかのプレースホルダー グラフィックをユーザーに表示して、空白スペースだけを表示しないようにすることができます。

于 2012-06-14T19:57:27.100 に答える
0

Thanks for the answers. I laughed at myself and then went to bed after reading the answers. Let me share how I resolved this problem - it uses some pieces of the answers:

I was trying to cache the large images in memory - this is unnecessary, why not store a lower res version and then load the hi res when the user stops scrolling? Then the user can scroll as fast as he likes and there will always be images in memory to quickly paint. When the user stops/slows scrolling, we load the hi res image.

Because he will be scrolling fast, he won't be able to see the lower res' lower quality. And, as there will only be one hi res to load, the ~250ms delay is hardly noticeable.

This really combines the best of both cases. And I can use the Android's methods for loading a lower res version of the Bitmap.

于 2012-06-16T22:55:08.573 に答える