2012-07-23 14 views
1

我遇到了一個巨大的問題HTC Wildfire S設備。我的應用程序開始第二個活動與圖像uri,用戶可以旋轉圖像,然後它被保存並返回到主要活動。問題是HTC只有第一張照片會被返回,第二個會與下面的錯誤導致應用程序崩潰:單個設備上的「無法壓縮回收的位圖」異常

java.lang.IllegalStateException: Can't compress a recycled bitmap at android.graphics.Bitmap.checkRecycled(Bitmap.java:372) at android.graphics.Bitmap.compress(Bitmap.java:799) at zapytaj.hot.or.not.ImageRotator.end(ImageRotator.java:151) at zapytaj.hot.or.not.ImageRotator$RotatorClass.onClick(ImageRotator.java:80) at android.view.View.performClick(View.java:2532) at android.view.View$PerformClick.run(View.java:9293) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:150) at android.app.ActivityThread.main(ActivityThread.java:4277) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) at dalvik.system.NativeStart.main(Native Method)

我看過,我應該.copy位圖,以避免在另一篇文章這個問題,但無法弄清楚,如何在我的代碼上做到這一點。謝謝你的幫助。第二個活動代碼如下:

package com.example.app; 
import java.io.ByteArrayOutputStream; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.content.ContentResolver; 
import android.content.ContentValues; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.database.Cursor; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Matrix; 
import android.graphics.drawable.BitmapDrawable; 
import android.net.Uri; 
import android.os.Bundle; 
import android.provider.MediaStore; 
import android.util.Base64; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.ImageButton; 
import android.widget.ImageView; 
import android.widget.Toast; 

public class ImageRotator extends Activity { 
    private static final String TAG = "Rotator"; 
    private Uri file; 
    private String suffix = ""; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.picture); 

     Bundle b = getIntent().getExtras(); 

     file = getIntent().getData(); 
     suffix = b.getString("suffix"); 

     Bitmap bm = this.getBitmap(); 


     ImageView box = (ImageView) findViewById(R.id.imageView1); 
     box.setImageBitmap(bm); 

     ImageButton v1 = (ImageButton) findViewById(R.id.rotateLeft); 
     ImageButton v2 = (ImageButton) findViewById(R.id.rotateRight); 
     ImageButton v3 = (ImageButton) findViewById(R.id.save); 
     v1.setOnClickListener(new RotatorClass()); 
     v2.setOnClickListener(new RotatorClass()); 
     v3.setOnClickListener(new RotatorClass()); 
    } 


    class RotatorClass implements ImageButton.OnClickListener 
    { 
     public void onClick(View v) { 
      final int id = v.getId(); 

      int change = 0; 

      switch(id) { 
       case R.id.rotateLeft: 
        change = -90; 
        break; 
       case R.id.rotateRight: 
        change = 90; 
        break; 
       case R.id.save: 
        end(true); 
        return; 
      } 

      Log.d(TAG, "change: "+change); 

      ImageRotator.this.rotate(change); 
     } 
    } 


    @Override 
    public void onBackPressed() { 
     final AlertDialog alertDialog = new AlertDialog.Builder(this).create(); 
     alertDialog.setTitle("Podane zdjęcie nie zostanie dodane. Kontynuować?"); 
     alertDialog.setButton("Tak", new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        end(false); 
       } 
     }); 

     alertDialog.setButton2("Nie", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       alertDialog.cancel(); 
      } 
     }); 

     alertDialog.setCancelable(false); 
     alertDialog.show(); 
    } 

    public void rotate(int change) { 
     // TODO Auto-generated method stub 

     ImageView imageView = (ImageView) findViewById(R.id.imageView1); 

     BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable(); 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     Bitmap bm = drawable.getBitmap(); 
     Matrix matrix = new Matrix(); 
     matrix.postRotate(change); 

     Bitmap bm2 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); 
     bm = null; 

     imageView.setImageBitmap(bm2);  
    } 

    public String getRealPathFromURI(Uri contentUri) { 
     String[] proj = { MediaStore.Images.Media.DATA }; 
     Cursor cursor = managedQuery(contentUri, proj, null, null, null); 
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 
     return cursor.getString(column_index); 
    } 

    public void end(boolean save) { 

     Intent in = new Intent(); 

     if(save == true) { 

      File file2 = new File(getRealPathFromURI(file)); 

      try { 
       FileOutputStream fos = new FileOutputStream(file2); 
       ImageView imageView = (ImageView) findViewById(R.id.imageView1); 
       BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable(); 
       Bitmap bm = drawable.getBitmap(); 

       ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
       bm.compress(Bitmap.CompressFormat.JPEG, 30, baos); 
       byte[] b = baos.toByteArray(); 

       String base = Base64.encodeToString(b, Base64.NO_WRAP); 

       bm.compress(Bitmap.CompressFormat.PNG, 90, fos); 
       fos.flush(); 
       fos.close(); 

       bm.recycle(); 
       bm = null; 

       in.setData(file); 

       in.putExtra("base", base); 
       System.gc(); 
      } catch (FileNotFoundException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     setResult(4,in); 
     finish(); 
    } 


    private Bitmap getBitmap() { 

     Uri uri = this.file; 
     InputStream in = null; 

     ContentResolver mContentResolver = getContentResolver(); 

     try { 
      final int IMAGE_MAX_SIZE = 300000; 
      in = mContentResolver.openInputStream(uri); 

      // Decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 
      BitmapFactory.decodeStream(in, null, o); 
      in.close(); 

      int scale = 1; 
      while ((o.outWidth * o.outHeight) * (1/Math.pow(scale, 2)) > IMAGE_MAX_SIZE) { 
       scale++; 
      } 
      Log.d(TAG, "scale = " + scale + ", orig-width: " + o.outWidth  + ", orig-height: " + o.outHeight); 

      Bitmap b = null; 
      in = mContentResolver.openInputStream(uri); 
      if (scale > 1) { 
       scale--; 
       // scale to max possible inSampleSize that still yields an image 
       // larger than target 
       o = new BitmapFactory.Options(); 
       o.inSampleSize = scale; 
       b = BitmapFactory.decodeStream(in, null, o); 

       // resize to desired dimensions 
       int height = b.getHeight(); 
       int width = b.getWidth(); 
       Log.d(TAG, "1th scale operation dimenions - width: " + width + ", height: " + height); 

       double y = Math.sqrt(IMAGE_MAX_SIZE 
         /(((double) width)/height)); 
       double x = (y/height) * width; 

       Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,  (int) y, true); 
       b.recycle(); 
       b = null; 

       b = scaledBitmap; 
      } else { 
       b = BitmapFactory.decodeStream(in); 
      } 
      in.close(); 
      return b; 
     } catch (IOException e) { 
      Log.e(TAG, e.getMessage(),e); 
      return null; 
     } 
    } 
} 

回答

2

只使用原始位圖的複製工具。

Bitmap bm = drawable.getBitmap().copy(Bitmap.Config.ARGB_8888, false);

Config - 具有兩個或三個可選值的枚舉,支持pixcel表示。

布爾參數指出結果位圖是否允許訪問來編輯它的位。