calculateInSampleSize()用于位图图像问题

时间:2013-07-05 10:59:24

标签: android memory bitmap

我在我的应用程序中在ImageView中显示位图图像时遇到了很大的问题。我有一个活动,显示2列4行的8张照片。当我点击这8张照片中的任何照片时,照片应该与设备尺寸一样大。但在这里我有一个问题是,当我点击任何照片时,它会给我一些OutOfMemoryError错误。请参考我的下面的代码,我在imageView中显示这张大照片:

public class ViewFullImage extends Activity {

    private Bitmap bitmap_general;
    private ImageView iv;
    private static final String path = "mfc/cam_img/";
    private int s_id;
    private int intentKey;
    private int width;
    private int height;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.view_draw_picture);

//  Display  display= ((WindowManager) getSystemService(ViewFullImage.WINDOW_SERVICE)).getDefaultDisplay();
//  width = display.getWidth(); 
//  height = display.getHeight(); 

    Display mDisplay= ((Activity) this).getWindowManager().getDefaultDisplay();
    width= mDisplay.getWidth();
    height= mDisplay.getHeight();

    Log.v("","===================== viewFullImage.java================");

    Log.v("","This is height ViewImage : "+height/2);
    Log.v("","This is width ViewImage : "+width/2);

    s_id=getIntent().getIntExtra("s_id", -1);
    intentKey=getIntent().getIntExtra("iv", -1);

    iv = (ImageView)findViewById(R.id.image);

    new LongOperation().execute();

    }

    //Image Rotation
    Bitmap rotateBitmap(Bitmap bitmap)
    {
        Matrix matrix = new Matrix();
        matrix.postRotate(90);
        Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0, 
                bitmap.getWidth(), bitmap.getHeight(), 
                                      matrix, true);
        bitmap.recycle();
        bitmap=null;

        return bitmap1;
    }

    //Calculate Image size
    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 larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }

    return inSampleSize;
}
    public void onDestroy() {
        super.onDestroy();
        System.gc();
    }

    public static Bitmap decodeSampleImage(File f, int width, int height) {
        try {
            System.gc(); // First of all free some memory

            // 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 requiredWidth = width;
            final int requiredHeight = height;

            // Find the scale value (as a power of 2)

            int sampleScaleSize = 1;

            while (o.outWidth / sampleScaleSize / 2 >= requiredWidth && o.outHeight / sampleScaleSize / 2 >= requiredHeight)
                sampleScaleSize *= 2;

            // Decode with inSampleSize

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

            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (Exception e) {
            Log.v("", e.getMessage()); // We don't want the application to just throw an exception
        }

        return null;
    }

    int h;
    int w;

    class LongOperation extends AsyncTask<String, Void, String> {
        private ProgressDialog Dialog = new ProgressDialog(ViewFullImage.this);

        @Override
        protected String doInBackground(String... aurl) {

            runOnUiThread(new Runnable() {

            public void run() {
                // TODO Auto-generated method stub

                File Dir= Environment.getExternalStorageDirectory();
                File imageDirectory = new File(Dir,path);
                File file  = new File(imageDirectory, "img_"+s_id+"_"+intentKey+".jpg");

                String ImgFile_Name = file.getAbsolutePath();
                BitmapFactory.Options options = new BitmapFactory.Options();
                BitmapFactory.decodeFile(file.getAbsolutePath(),options);

                h = options.outHeight;
                w = options.outWidth;

                options.inSampleSize = calculateInSampleSize(options, width/5, height/5);
                options.inJustDecodeBounds = false;
                options.inScaled=true;

                if(bitmap_general!=null){
                    bitmap_general.recycle();
                    bitmap_general=null;
                }

                bitmap_general = BitmapFactory.decodeFile(ImgFile_Name,options);

                try {
                    if(h<w)
                    {
                        iv.setImageBitmap(rotateBitmap(bitmap_general));
                    }
                    else{
                        iv.setImageBitmap(bitmap_general);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    if(bitmap_general!=null){
                        bitmap_general.recycle();
                        bitmap_general=null;
                    }
                    System.gc();
                }
                finally{
                    if(bitmap_general!=null){
                        bitmap_general.recycle();
                        bitmap_general=null;
                    }
                    System.gc();
                }
            }
        });

        return null;
    }

    protected void onPreExecute() {
            Dialog.setMessage("Loading Image...");
            Dialog.show();
    }

    protected void onPostExecute(String resultGot) {
        Dialog.dismiss();
    }
 }
}

Xml布局文件:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    android:id="@+id/RootView">

    <ImageView
        android:id="@+id/image"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:adjustViewBounds="true"/>

</RelativeLayout>

在上面的代码中,我有点混淆应该在下面的语句中输入的高度和宽度值:

options.inSampleSize = calculateInSampleSize(options, width, height); 

请有人告诉我我的代码在哪里做坏事吗?

1 个答案:

答案 0 :(得分:0)

似乎你根本没有使用decodeSampleImage,而是你正在调用BitmapFactory.decodeFile(file.getAbsolutePath(),options);因此,您无法正确处理大图像。 Here您可以找到有关如何有效加载大图像的有用信息。您可以将它作为起点。