3

画像をキャプチャしてビットマップに変換し、Rest サービスに投稿する Android アプリに取り組んでいます。

Bitmap の作成中に、BitmapFactory.Options.isSample Size の値を 4 に設定しました。これは、HTC One を除くすべてのデバイスで正常に機能します。HTC one の画像が歪んでいます。

値を 1 に変更すると、HTC 1 では適切な画像が表示されますが、メモリの問題により、他のすべてのデバイスではアプリケーションがクラッシュします。

この問題は、使用可能なヒープ サイズに関連しています。

  1. HTC one が HTC one で歪んだ画像を表示する理由は何ですか。
  2. 同じビルド バージョンの 16 でも S3 でアプリケーションがクラッシュするのはなぜですか。ヒープ サイズが利用できないためにクラッシュします。
  3. ドロイドのようなすべての下位バージョンの電話がサンプルサイズ4で正常に動作するのはなぜですか.
  4. アプリの利用可能なメモリ領域を確認し、BITMAP を操作するために利用可能なものを使用する最良の方法は何ですか。

マニフェスト ファイルで android:largeHeap を構成すると、これは機能しているように見えますが、信頼できるソリューションではないようです。


カメラ パラメーターを使用して撮影した写真のサイズを見つけ、ビットマップの最適なサンプル サイズにたどり着くことができました。以下のコードは問題を解決します。しかし、それは正しい方法ですか、それとも1と4を使用する代わりにサンプルサイズも計算する必要がありますか.

private Bitmap createImaegBitmap(byte[] data)
    {
        BitmapFactory.Options opt;

        opt = new BitmapFactory.Options();
        opt.inTempStorage = new byte[16 * 1024];
        Parameters parameters = ((ReceiptCollection)getApplication()).getParams();
        Size size = parameters.getPictureSize();

        int height11 = size.height;
        int width11 = size.width;
        float mb = (width11 * height11) / 1024000;

        if (mb > 4f)
            opt.inSampleSize = 4;
        else if (mb > 3f)
            opt.inSampleSize = 1;
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,opt);
        return bitmap;
    }
4

1 に答える 1

4

見てください:
http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html

1: なぜなら... Direct FROM DOC: 値 > 1 に設定されている場合、デコーダーに元の画像をサブサンプリングするように要求し、メモリを節約するためにより小さい画像を返します。サンプル サイズは、デコードされたビットマップ内の 1 つのピクセルに対応する、いずれかの次元のピクセル数です。たとえば、inSampleSize == 4 は、元の幅/高さが 1/4、ピクセル数が 1/16 のイメージを返します。任意の値 <= 1 は 1 と同じように扱われます。注: デコーダーは 2 の累乗に基づく最終値を使用します。その他の値は最も近い 2 の累乗に切り捨てられます。

2:私の推測では、すべてのデバイスが同じメモリを使用できるわけではないためです。3:数値を設定するだけでなく、サンプルサイズを計算する必要があります...

2,3: すべてのデバイスのカメラ解像度が異なります。

この問題に取り組むには、これを読んでください: http://developer.android.com/training/displaying-bitmaps/index.html

    public static Bitmap lessResolution(String filePath) {
    int reqHeight = 120;
    int reqWidth = 120;
    BitmapFactory.Options options = new BitmapFactory.Options();

    // First decode with inJustDecodeBounds=true to check dimensions
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeFile(filePath, options);
}

private static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {

    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and
        // width
        final int heightRatio = Math.round((float) height
                / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will
        // guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    return inSampleSize;
}
于 2013-08-14T22:51:02.470 に答える