6

Tôi đang làm việc trong một ứng dụng Android và tôi đang sử dụng bitmap để liên kết hình ảnh với ImageView. Yêu cầu của tôi là xoay ImageView đó và tạo một đường viền cho ImageView đó. Tôi đã thực hiện thành công điều này, nhưng sau khi ứng dụng sử dụng hoạt động này hai ba lần một lỗi "lực đóng" xuất hiện nói rằng Bitmap ra khỏi bộ nhớ VM. Hãy giúp tôi giảm thiểu mức tiêu thụ bộ nhớ bitmap trong mã của tôi. Và cho tôi biết làm thế nào để sửa đổi mã cho cùng?Bitmap lỗi bộ nhớ trong android ...

final int BORDER_WIDTH = 5; 
     // Set the border color 
     final int BORDER_COLOR = Color.WHITE; 
     Bitmap res = Bitmap.createBitmap(CAPTURE_IMAGE.getWidth() + 2 
       * BORDER_WIDTH, CAPTURE_IMAGE.getHeight() + 2 * BORDER_WIDTH, 
       CAPTURE_IMAGE.getConfig()); 
     System.gc(); 
     Canvas canvas = new Canvas(res); 
     Paint paint = new Paint(); 
     paint.setColor(BORDER_COLOR); 
     canvas.drawRect(0, 0, res.getWidth(), res.getHeight(), paint); 

     canvas.drawBitmap(CAPTURE_IMAGE, BORDER_WIDTH, BORDER_WIDTH, paint); 
     Matrix mat = new Matrix(); 
     // Set the Imageview position 
     mat.postRotate(355); 

     bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(), 
       res.getHeight(), mat, true); 
     System.gc(); 
     res.recycle(); 
     res = null; 
     paint = null; 
     canvas = null; 
     mat = null; 
     // Set the captured bitmap image in the imageview 
     mShareImageView.setImageBitmap(bMapRotate); 
+1

tôi đã tạo một giải pháp JNI tốt để tránh hết bộ nhớ bằng cách xóa hàng rào giới hạn kích thước heap tối đa. [** đây là liên kết **] (http://stackoverflow.com/questions/14398670/android-rotating-a-bitmap-using-jni-ndk#comment20033361_14398670) vào đoạn trích của tôi. một số lưu ý: - thay thế trong mã mỗi trường hợp của "uint16_t" với "uint32_t" (đó là lỗi trên mã của tôi mà tôi đã hỏi). - bitmap đầu vào và đầu ra phải có cấu hình 8888 (là ARGB) - bitmap đầu vào sẽ được tái chế trong quá trình xử lý. - mã xoay hình ảnh 90 đồng hồ đếm ngược suy thoái. tất nhiên bạn có thể thay đổi nó tùy thuộc vào –

Trả lời

3

Tôi nghĩ rằng bạn nên sử dụng chức năng co lại như thế này

bMapRotate = Bitmap.createBitmap(res, 0, 0, res.getWidth(), 
       res.getHeight(), mat, true); 


Bitmap myBitmap = ShrinkBitmap(bMapRotate , 300, 300); 

mShareImageView.setImageBitmap(myBitmap); 


private Bitmap ShrinkBitmap(String file, int width, int height) { 
     // TODO Auto-generated method stub 
     BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options(); 
     bmpFactoryOptions.inJustDecodeBounds = true; 
     Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 

     int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height); 
     int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width); 

     if (heightRatio > 1 || widthRatio > 1) 
     { 
     if (heightRatio > widthRatio) 
     { 
      bmpFactoryOptions.inSampleSize = heightRatio; 
     } else { 
      bmpFactoryOptions.inSampleSize = widthRatio; 
     } 
     } 

     bmpFactoryOptions.inJustDecodeBounds = false; 
     bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions); 
    return bitmap; 
    } 

nó làm việc cho tôi và tôi tránh Bitmap ra khỏi VM memory exception

+1

Xin chào.Cảm ơn câu trả lời.Nhưng trong phương thức ShrinkBitmap nó chuyển một tệp tham số mà tôi không có. – Arun

+1

nhưng bạn phải chọn tệp từ một số nơi bạn không thể sử dụng –

+1

Điều này sẽ thay đổi kích thước hình ảnh kết quả ... – Caner

1

Hãy thử di chuyển các cuộc gọi gc() đến cùng. Nó nên chạy sau khi bạn đặt res = null để nó có thể giải phóng bộ nhớ không sử dụng:

res.recycle(); 
    res = null; 
    paint = null; 
    canvas = null; 
    mat = null; 
    System.gc(); 
3

trong tập tin mainfest thêm ---> android: largeHeap: "true"

+0

Chỉ cần một lưu ý cho người khác: Tôi đã thử đặt thẻ này vào các thẻ '' trong tệp kê khai, thẻ gây ra lỗi và nó không hoạt động. Nhưng khi tôi đặt nó vào các thẻ '' nó hoạt động. Ngoài ra, phải là 'android: largeHeap =" true "'. Chỉ sử dụng một dấu hai chấm. – Azurespot

0

Chỉ cần thêm android: largeHeap = "true "trong tệp kê khai của bạn

Ref: largeHeap = thẻ manifest true không hoạt động?

Các vấn đề liên quan