1

カメラまたはギャラリーから画像を取得しようとすると、エラーが発生します。以下は logcat の一部です。

06-27 05:51:47.297: E/dalvikvm-heap(438): Out of memory on a 35295376-byte allocation.
06-27 05:51:47.312: E/dalvikvm(438): Out of memory: Heap Size=108067KB, Allocated=71442KB, Limit=131072KB
06-27 05:51:47.312: E/dalvikvm(438): Extra info: Footprint=108067KB, Allowed Footprint=108067KB, Trimmed=56296KB
06-27 05:51:47.312: E/PowerManagerService(438): Excessive delay when setting lcd brightness: mLcdLight.setBrightness(176, 1) spend 288ms, mask=2
06-27 05:51:48.052: E/dalvikvm-heap(4332): Out of memory on a 24023056-byte allocation.
06-27 05:51:48.057: E/dalvikvm(4332): Out of memory: Heap Size=63139KB, Allocated=40922KB, Limit=65536KB
06-27 05:51:48.057: E/dalvikvm(4332): Extra info: Footprint=63139KB, Allowed Footprint=63139KB, Trimmed=0KB
06-27 05:51:48.057: E/EmbeddedLogger(438): App crashed! Process: <my_app_name>

画像を取得するためのコードは次のとおりです。

Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

Intent chooserIntent = Intent.createChooser(pickIntent, "Select or take a new Picture");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent });
startActivityForResult(chooserIntent, selectPic);

そしてonActivityResult()私は:

Bitmap bitmapSelectedImage = null;
Uri selectedImage =  data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };

Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();

String filePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
cursor.close();
bitmapSelectedImage = BitmapFactory.decodeFile(filePath); // Here is where do I get error.

オンラインでエラーが発生しbitmapSelectedImage = BitmapFactory.decodeFile(filePath);ます。

私はそれについて多くのウェブサイト/トピックを見てきましたが、誰も助けてくれませんでした.

助言がありますか?

4

5 に答える 5

6

あなたのメモリ割り当てヒープサイズは非常に限られています。ファイルからヒープに高解像度の画像をロードしようとすると、簡単にメモリ不足エラーが発生する可能性があります。

カメラ アプリが実際に非常に高い解像度を使用していると仮定すると (ほぼ確実にそうです)、表示に必要なサイズのビットマップのスケーリングされたバージョンのみをメモリにロードする必要があります。

すでに参照するように提案されているドキュメント - http://developer.android.com/training/displaying-bitmaps/load-bitmap.html は、まさにそれを行うための完全な機能メソッドを提供します。

1)最初のステップは、必要なスケールを(メモリにロードせずに)計算することです。それがcalculateInSampleSize方法です。

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    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 smaller than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}

2) 2 番目のステップは、ステップ 1 を使用した完全な方法です。

public static Bitmap getSampleBitmapFromFile(String bitmapFilePath, int reqWidth, int reqHeight) {
    // calculating image size
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(new FileInputStream(new File(bitmapFilePath)), null, options);

    int scale = calculateInSampleSize(options, reqWidth, reqHeight);

    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;

    return BitmapFactory.decodeStream(new FileInputStream(new File(bitmapFilePath)), null, o2);

}

reqHeightおよびreqWithは、画像を表示する画像ビューのピクセル単位の高さと幅です。画像ビューが 100x100 ピクセルであるとしましょう。必要なことは次のとおりです。

bitmapSelectedImage = getSampleBitmapFromFile(filePath, 100, 100);
于 2013-06-27T04:04:51.797 に答える
1

ビットマップのサイズが非常に大きいか、処理が効率的でない場合、この問題が発生します。ビットマップを効率的にデコードするには、Android 開発者サイトでこれらのヒントを確認できます。

ビットマップを効率的に表示する

于 2013-06-27T03:07:59.680 に答える
1

ビットマップに強い参照を使用しないでください。以下のように使用してください。システムがオブジェクトをgcしてメモリリークを減らすことができるように、常にweakreferencesを使用してください

WeakReference<Bitmap> bitmapSelectedImage ;
于 2013-06-27T03:38:00.660 に答える
0

画像を縮小する必要があります。

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html .

適切なBitmap.decode方法を使用して、画像を縮小します。

Bitmap.decode

例 :

必要なパラメーターを指定してメソッドを呼び出します。

public static Bitmap decodeFile(File f,int WIDTH,int HIGHT){
 try {
     //Decode image size
     BitmapFactory.Options o = new BitmapFactory.Options();
     o.inJustDecodeBounds = true;
     BitmapFactory.decodeStream(new FileInputStream(f),null,o);

     //The new size we want to scale to
     final int REQUIRED_WIDTH=WIDTH;
     final int REQUIRED_HIGHT=HIGHT;
     //Find the correct scale value. It should be the power of 2.
     int scale=1;
     while(o.outWidth/scale/2>=REQUIRED_WIDTH && o.outHeight/scale/2>=REQUIRED_HIGHT)
         scale*=2;

     //Decode with inSampleSize
     BitmapFactory.Options o2 = new BitmapFactory.Options();
     o2.inSampleSize=scale;
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
 } catch (FileNotFoundException e) {}
 return null;
}
于 2013-06-27T04:04:15.467 に答える