5

このエラーに関してstackoverflowで多くの質問に出くわしましたが、私のシナリオの適切な解決策を説明しているものはありませんでした。

私のAndroidアプリケーションでは、ユーザーがボタンをクリックしてギャラリーを開き、画像を選択できるようにする必要があります。そして、その特定の選択した画像を私のレイアウト(UI)のImageViewにロードする必要があります。

これを行うと、かなり問題ありません。以下は、これを達成するために使用しているコードです。

[アップロード] ボタンでクリック ->

        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent,"Select Picture"), REQUEST_UPLOAD_IMG);

そして onActivityResult ->

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{       
    //super.onActivityResult(requestCode, resultCode, data);        
    if(resultCode == Activity.RESULT_OK)
    {
        if(requestCode==REQUEST_UPLOAD_IMG)
        {               
            Uri selectedImageURI = data.getData();
            uploadImgVW.setImageURI(selectedImageURI);              
        }
        else
        {
            Toast.makeText(MainActivity.this, "You can only select an Image.", Toast.LENGTH_LONG).show();
        }
    }
}

ただし、ユーザーがより大きなサイズ ( 2MBなど) の画像を選択すると、アプリケーションは次のエラーで終了します。しかし、通常の (KB レベルの) 画像では問題なく、この問題 (このエラー状況を処理するには) に対して何ができるか疑問に思っています。ありがとう...

エラー ->

06-20 16:43:58.445: E/AndroidRuntime(2075): FATAL EXCEPTION: main
06-20 16:43:58.445: E/AndroidRuntime(2075): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
4

3 に答える 3

7

ビットマップを効率的に管理する方法を説明する一連の記事があります。コードを見ると、その大きさを知らずに画像を読み込むと、特に多くの画像を読み込んで処理する場合に、最終的にこれらの問題に直面することになります。

これらの記事の 1 つで説明されているアイデアは、既に縮小されたビットマップを読み込むことです (まず、読み込む画像の大きさを確認し、次に縮小率を計算してから、縮小した画像を読み込みます)。 . そのためには、最初に ImageView のサイズを知る必要があります。次に、表示するターゲット ファイルの Uri があるため、BitmapFactory.decode(...)を使用する必要があります。ファイルへの URI は自明である必要があります。

また、アプリのメモリ消費量も確認する必要があります...メモリにハングアップしている他のリソースがあり、それらをクリーンアップする必要がある場合があります。私は非常に便利なツールMATを使用しています。これに関する非常に優れた記事がここにあります。著者の Patrick Dubroy は、このトピックに関する非常に興味深いセッションを Google IO 2011 で開催しました。それをチェックしてください、私にとってはとても役に立ちました...

于 2013-06-21T13:32:17.900 に答える
1

画像のサイズを変更してから設定します

public static Bitmap decodeUri(Context c, Uri uri, final int requiredSize) 
            throws FileNotFoundException {
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o);

        int width_tmp = o.outWidth
                , height_tmp = o.outHeight;
        int scale = 1;

        while(true) {
            if(width_tmp / 2 < requiredSize || height_tmp / 2 < requiredSize)
                break;
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(c.getContentResolver().openInputStream(uri), null, o2);
    }   

または、そのように使用できます

if(resultCode == RESULT_OK){  
                Uri selectedImage = data.getData();
                InputStream imageStream = null;
                try {
                    imageStream = getContentResolver().openInputStream(selectedImage);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
                profileImage.setImageBitmap(Bitmap.createScaledBitmap(yourSelectedImage , 120, 120, false));
                }
于 2013-06-21T13:35:50.763 に答える