14

Androidアプリでやや大きな画像を表示する必要があります。現在、ソースビットマップでImageViewを使用しています。openGLには、画像を処理するために画像のサイズを大きくすることができるという、デバイスに依存しない特定の制限があることを理解しています。

画像を複数のImageView要素に分割する以外に、この制限に関係なく、これらの画像を(固定幅で、トリミングせずに)表示する方法ありますか?

ありがとうございました。

UPDATE 01 Apr 2013 これまでのところ、すべての提案は画質を下げることでした。GPUを使用する代わりにCPUを使用して処理を行うことで、この制限を回避できる可能性があることを示唆しました(ただし、処理に時間がかかる場合があります)。わかりませんが、画質を落とさずに固定幅の長い画像を表示する方法は本当にありませんか?きっとあるでしょう、誰かが少なくとも私を正しい方向に向けてくれるなら、私はそれが大好きです。

みんな、ありがとう。

4

4 に答える 4

10

を使用BitmapRegionDecoderして、より大きなビットマップを分解できます(APIレベル10が必要です)。このクラスを利用して、 :Drawable内に配置できるシングルを返すメソッドを作成しました。ImageView

private static final int MAX_SIZE = 1024;

private Drawable createLargeDrawable(int resId) throws IOException {

    InputStream is = getResources().openRawResource(resId);
    BitmapRegionDecoder brd = BitmapRegionDecoder.newInstance(is, true);

    try {
        if (brd.getWidth() <= MAX_SIZE && brd.getHeight() <= MAX_SIZE) {
            return new BitmapDrawable(getResources(), is);
        }

        int rowCount = (int) Math.ceil((float) brd.getHeight() / (float) MAX_SIZE);
        int colCount = (int) Math.ceil((float) brd.getWidth() / (float) MAX_SIZE);

        BitmapDrawable[] drawables = new BitmapDrawable[rowCount * colCount];

        for (int i = 0; i < rowCount; i++) {

            int top = MAX_SIZE * i;
            int bottom = i == rowCount - 1 ? brd.getHeight() : top + MAX_SIZE;

            for (int j = 0; j < colCount; j++) {

                int left = MAX_SIZE * j;
                int right = j == colCount - 1 ? brd.getWidth() : left + MAX_SIZE;

                Bitmap b = brd.decodeRegion(new Rect(left, top, right, bottom), null);
                BitmapDrawable bd = new BitmapDrawable(getResources(), b);
                bd.setGravity(Gravity.TOP | Gravity.LEFT);
                drawables[i * colCount + j] = bd;
            }
        }

        LayerDrawable ld = new LayerDrawable(drawables);
        for (int i = 0; i < rowCount; i++) {
            for (int j = 0; j < colCount; j++) {
                ld.setLayerInset(i * colCount + j, MAX_SIZE * j, MAX_SIZE * i, 0, 0);
            }
        }

        return ld;
    }
    finally {
        brd.recycle();
    }
}

MAX_SIZEこのメソッドは、描画可能なリソースが両方の軸で(1024)よりも小さいかどうかを確認します。そうである場合は、ドローアブルを返すだけです。そうでない場合は、画像を分解し、画像のチャンクをデコードして、に配置しますLayerDrawable

利用可能なほとんどの電話が少なくともその大きさの画像をサポートすると信じているので、1024を選択しました。電話の実際のテクスチャサイズの制限を知りたい場合は、OpenGLを介してファンキーなことを行う必要がありますが、それは私が掘り下げたかったことではありません。

画像にどのようにアクセスしているかわからなかったので、画像は描画可能なフォルダにあると思いました。そうでない場合は、メソッドをリファクタリングして、必要なパラメーターを取り込むのはかなり簡単です。

于 2013-04-07T12:25:22.543 に答える
3

BitmapFactoryOptions画像のサイズを小さくするために使用できます。次のようなものを使用できます。

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3; //reduce size 3 times
于 2013-03-27T09:47:55.147 に答える
2

マップがどのように機能するかを見たことがありますか?マップのレンダラーを一度作成しました。同じトリックを使用して画像を表示できます。

画像を正方形のタイル(128x128ピクセルなど)に分割します。タイルからのレンダリングをサポートするカスタムimageViewを作成します。imageViewは、ビットマップのどの部分を表示するかを認識しており、SDカードからそれらをロードする必要なタイルのみを表示します。このようなタイルマップを使用すると、無限の画像を表示できます。

于 2013-04-02T12:59:31.567 に答える
0

ビットマップの寸法を教えていただければ助かります。

OpenGLは自然な数学的制限に反して実行されることを理解してください。

たとえば、OpenGLのテクスチャが2のx乗でなければならないという非常に正当な理由があります。これは、実際には、ダウンスケーリングの計算を余りなくきれいに実行できる唯一の方法です。

したがって、問題を引き起こしている最小のビットマップの正確な寸法を教えていただければ、実際にどのような制限に直面しているのかを教えてくれる人もいるかもしれません。

于 2013-04-02T08:53:48.137 に答える