1

I am trying to display a big amount of pictures into a viewer I found on a website

It's is working very well with <20 pictures, but after that I got a "OutOfMemory"

I added this code, found on stackoverflow but it looks like it's not enough

                bmpOptions.inSampleSize = sampleSize;
                bmpOptions.inDither=false;                     //Disable Dithering mode
                bmpOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
                bmpOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
                bmpOptions.inTempStorage=new byte[32 * 1024];

How could I improve it ? Here's the full code

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode == RESULT_OK) {
        // check if we are returning from picture selection
        if (requestCode == PICKER) {
            // the returned picture URI
            Uri pickedUri = data.getData();
            // declare the bitmap
            Bitmap pic = null;
            // declare the path string
            String imgPath = "";
            // retrieve the string using media data
            String[] medData = { MediaStore.Images.Media.DATA };
            // query the data
            Cursor picCursor = managedQuery(pickedUri, medData, null, null,
                    null);
            if (picCursor != null) {
                // get the path string
                int index = picCursor
                        .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                picCursor.moveToFirst();
                imgPath = picCursor.getString(index);
            } else
                imgPath = pickedUri.getPath();
            // if we have a new URI attempt to decode the image bitmap
            if (pickedUri != null) {
                // set the width and height we want to use as maximum
                // display
                int targetWidth = 600;
                int targetHeight = 400;
                // create bitmap options to calculate and use sample size
                BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
                // first decode image dimensions only - not the image bitmap
                // itself
                bmpOptions.inDither=false;                     //Disable Dithering mode
                bmpOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
                bmpOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
                bmpOptions.inTempStorage=new byte[32 * 1024];
                bmpOptions.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(imgPath, bmpOptions);
                // image width and height before sampling
                int currHeight = bmpOptions.outHeight;
                int currWidth = bmpOptions.outWidth;
                // variable to store new sample size
                int sampleSize = 1;
                // calculate the sample size if the existing size is larger
                // than target size
                if (currHeight > targetHeight || currWidth > targetWidth) {
                    // use either width or height
                    if (currWidth > currHeight)
                        sampleSize = Math.round((float) currHeight
                                / (float) targetHeight);
                    else
                        sampleSize = Math.round((float) currWidth
                                / (float) targetWidth);
                }
                // use the new sample size
                bmpOptions.inSampleSize = sampleSize;
                bmpOptions.inDither=false;                     //Disable Dithering mode
                bmpOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared
                bmpOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
                bmpOptions.inTempStorage=new byte[32 * 1024];
                // now decode the bitmap using sample options
                bmpOptions.inJustDecodeBounds = false;
                // get the file as a bitmap
                pic = BitmapFactory.decodeFile(imgPath, bmpOptions);
                // pass bitmap to ImageAdapter to add to array
                imgAdapt.addPic(pic);
                // redraw the gallery thumbnails to reflect the new addition
                picGallery.setAdapter(imgAdapt);
                // display the newly selected image at larger size
                picView.setImageBitmap(pic);
                // scale options
                picView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                pic.recycle();
            }

        }
    }
4

2 に答える 2

1

まず、ヒープ サイズが 20 枚の画像の後に増加していることをトレースします。この単純なソリューションを試すことができます。画像と幅と高さを渡すだけで、サイズ変更された画像が返されます。

public static Bitmap getResizedBitmap(Bitmap image, int newHeight, int newWidth) {
    int width = image.getWidth();
    int height = image.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    // create a matrix for the manipulation
    Matrix matrix = new Matrix();
    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);
    // recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(image, 0, 0, width, height,
            matrix, false);
    return resizedBitmap;
}
于 2013-01-17T13:49:50.343 に答える
1

サイズ変更ビットマップコードを配置した後、ビットマップをスケーリングする必要があります。または、画像ビューに直接設定して、これを試してください

int h = 100; // height in pixels
int w = 100; // width in pixels
Bitmap photoBitMap = Bitmap.createScaledBitmap(yourSelectedImage, h, w, true);
imageView.setBitmap(photoBitMap);
于 2013-01-17T14:04:00.373 に答える