1

我越来越

画布:尝试使用回收的位图 android.graphics.Bitmap@4057a3a8

每次我试图展示一张图片。 图片

当我删除 bmp.recycle() 时,一切顺利,但我没有在我的代码中使用这个图像,所以我不明白问题出在哪里。

package com.example.photobooth;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;

public class EditorActivity extends Activity implements OnClickListener{

    String path = null;

    private int screen_height;
    private int screen_width;

    private Bitmap setUpImage(Bitmap image) {

        int min_side = Math.min(screen_height, screen_width);
        float scale_factor = (float) (((float) min_side / image.getWidth()) * 1.5);
        float[] scalef = { scale_factor, scale_factor };
        Bitmap scaled_image = ImageUtilities.scaleImage(image, scalef);

        return scaled_image;

    }

    private void setUp() {

        Bundle b = getIntent().getExtras();
        if (b != null) {
            path = b.getString("path");
        }

        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);

        this.screen_height = metrics.heightPixels;
        this.screen_width = metrics.widthPixels;

        int min_measure = Math.min(screen_width, screen_height);

        // Make ImageView square
        ImageView img = (ImageView) findViewById(R.id.photo_holder);
        android.view.ViewGroup.LayoutParams lp = img.getLayoutParams();
        lp.height = min_measure;
        img.setLayoutParams(lp);

        Bitmap bmp = BitmapFactory.decodeFile(path);
        final Bitmap ready_image = setUpImage(bmp);
        bmp.recycle();

        ImageView iv = (ImageView) findViewById(R.id.photo_holder);
        iv.setImageBitmap(ready_image);

        // set up touch event for imageview(photo_holder)

        img.setOnTouchListener(new OnTouchListener() {

            float touch_x, touch_y, scrolled_x = 0.0f, scrolled_y = 0.0f;

            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:

                    touch_x = event.getX();
                    touch_y = event.getY();

                    break;

                case MotionEvent.ACTION_MOVE:

                    float cur_x = event.getX();
                    float cur_y = event.getY();


                    float scroll_x = -cur_x + touch_x;
                    float scroll_y = -cur_y + touch_y;

                    scrolled_x += scroll_x;
                    scrolled_y += scroll_y;

                    if (scrolled_x > (ready_image.getWidth() - screen_width)/2
                            || scrolled_x < -(ready_image.getWidth() - screen_width)/2){
                        scrolled_x -= scroll_x;
                        scroll_x = 0;
                    }

                    if (scrolled_y > (ready_image.getHeight() - screen_width)/2
                            || scrolled_y < -(ready_image.getHeight() - screen_width)/2){
                        scrolled_y -= scroll_y;
                        scroll_y = 0;
                    }

                    v.scrollBy((int) (scroll_x),
                            (int) (scroll_y));

                    touch_x = cur_x;
                    touch_y = cur_y;

                    break;

                }

                return true;
            }
        });

        //Set up buttons
        Button btn = (Button)findViewById(R.id.save);
        btn.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                ImageView img = (ImageView)findViewById(R.id.photo_holder);
                int scroll_x = img.getScrollX();
                int scroll_y = img.getScrollY();

                int left = (ready_image.getWidth() - screen_width)/2
                        + scroll_x;

                int top = (ready_image.getHeight() - screen_width)/2
                        + scroll_y;

                int right = left + screen_width;

                int bottom = top + screen_width;

                Rect r = new Rect(left, top, right, bottom);

                Bitmap croped_image = ImageUtilities.cropImage(ready_image,
                        r,
                        screen_width,
                        screen_width);

                String path_to_folder = Environment.getExternalStorageDirectory()
                        .getAbsolutePath();

                String pic_path = path_to_folder + File.separator + MainActivity.app_name;

                File f = new File(pic_path);
                File picture = null;
                try {
                    picture = File.createTempFile("photo_", ".jpg", f);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                try {
                    FileOutputStream fos = new FileOutputStream(picture);
                    croped_image.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    fos.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (requestWindowFeature(Window.FEATURE_NO_TITLE))
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_editor);

        setUp();

    }

    public void onClick(View v) {
        // TODO Auto-generated method stub

    }

}

bmp 在 setUp() 方法中被回收。

ImageUtility 是

package com.example.photobooth;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;

public class ImageUtilities {

    public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input,
            int pixels, int w, int h, boolean squareTL, boolean squareTR,
            boolean squareBL, boolean squareBR, boolean border) {

        Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final float densityMultiplier = context.getResources()
                .getDisplayMetrics().density;

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, w, h);
        final RectF rectF = new RectF(rect);

        // make sure that our rounded corner is scaled appropriately
        final float roundPx = pixels * densityMultiplier;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        // draw rectangles over the corners we want to be square
        if (squareTL) {
            canvas.drawRect(0, 0, w / 2, h / 2, paint);
        }
        if (squareTR) {
            canvas.drawRect(w / 2, 0, w, h / 2, paint);
        }
        if (squareBL) {
            canvas.drawRect(0, h / 2, w / 2, h, paint);
        }
        if (squareBR) {
            canvas.drawRect(w / 2, h / 2, w, h, paint);
        }

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

        canvas.drawBitmap(input, 0, 0, paint);
        if (border) {
            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(Color.WHITE);
            paint.setStrokeWidth(3);
            canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
        }

        return output;
    }

    public static Bitmap cropImage(Bitmap origina_bmp, Rect rec, int w, int h) {

        Bitmap target_bitmap = Bitmap.createBitmap(w, h,
                Bitmap.Config.ARGB_8888);
        target_bitmap.setDensity(origina_bmp.getDensity());
        Canvas canvas = new Canvas(target_bitmap);
        canvas.drawBitmap(origina_bmp, new Rect(rec.left, rec.top, rec.right,
                rec.bottom), new Rect(0, 0, w, h), null);
        return target_bitmap;

    }

    public static Bitmap makeSquareImage(Bitmap original_image, int size){

        int min_side = Math.min(original_image.getWidth(),
                original_image.getHeight());
        int side_size = ImageUtilities.get2del(min_side);


        int crop_to;


        Bitmap croped_image = null;

        if (min_side == original_image.getWidth()){
            crop_to = (original_image.getHeight() - side_size) / 2;
            croped_image = ImageUtilities.cropImage(original_image, new Rect(
                    0, crop_to, original_image.getWidth(),
                    original_image.getHeight() - crop_to), size, size);
        }else{
            crop_to = (original_image.getWidth() - side_size) / 2;
            croped_image = ImageUtilities.cropImage(original_image, new Rect(
                    crop_to, 0, original_image.getWidth() - crop_to,
                    original_image.getHeight()), size, size);
        }

        return croped_image;

    }

    public static int get2del(int num) {

        while (num % 2 != 0)
            num++;

        return num;

    }

    public static Bitmap scaleImage(Bitmap originalBMP, float[] scaleFactor) {

        Matrix scaleMat = new Matrix();
        scaleMat.postScale(scaleFactor[0], scaleFactor[1]);
        Bitmap scaledImage = Bitmap.createBitmap(originalBMP, 0, 0,
                originalBMP.getWidth(), originalBMP.getHeight(), scaleMat,
                false);
        return scaledImage;

    }

}

所以它没有。如果我写 bmp = null 而不是 bmp.recycle() 一切都很好,但我想知道为什么在第二次机会中应用程序崩溃了。

4

1 回答 1

0

What is ImageUtilities? Maybe scaleImage may reuse the same image.

Does your program work correctly if you do:

bmp = null;

instead of

bmp.recycle();

?

The official documentation of recycle says: "This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap. "

So using "bmp = null" should be better than "bmp.recycle()".

于 2012-10-17T13:32:05.797 回答