2012-10-17 29 views
1

我越來越Android是試圖使用再生圖像

帆布:試圖使用回收的位圖 [email protected]

每次我試圖展現一個圖片。 Image

當我刪除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()一切正常,但我想知道爲什麼在第二次機會應用程序崩潰。

回答

0

什麼是ImageUtilities?也許scaleImage可能會重複使用相同的圖像。

請問你的程序的工作,如果你正確地做:的

bmp = null; 

代替

bmp.recycle(); 

循環的官方文件說: 「這是一個先進的呼叫,並且通常不需要叫,因爲正常的GC進程將釋放該內存的時候也有這種位圖沒有更多的引用。」

所以使用「bmp = null」應該比「bmp.recycle()」更好。