2012-05-18 36 views
6

Tôi có tệp có hình ảnh rất lớn: ví dụ: 9000x9000.Giải mã một phần của Bitmap từ tệp trong Android

Tôi không thể tải Bitmap trong bộ nhớ vì kích thước heap. Nhưng tôi chỉ cần hiển thị một phần nhỏ của bitmap này ví dụ chiều rộng rect = 100-200 và height = 200-400 (kích thước kết quả của bitmap phụ = 100x200)

Làm cách nào tôi có thể lấy bitmap này từ tập tin?

Lưu ý: Tôi không muốn để mất chất lượng trong hình ảnh 100x200

Cảm ơn

Trả lời

12

là nó có thể có một giải pháp cho việc này?

ví dụ: BitmapRegionDecoder.

Nó sẽ làm việc cho API10 trở lên ...

+0

dường như đó sẽ là câu trả lời đúng. – njzk2

+0

Cảm ơn, tôi vừa mới sử dụng nó. Nó hoạt động. –

0

Tôi không nghĩ rằng bạn có thể. Ngay cả trên PC, tôi không thấy cách bạn có thể làm điều đó mà không tải toàn bộ hình ảnh: hầu hết định dạng hình ảnh, ví dụ PNG, có dữ liệu pixel nén, vì vậy bạn cần giải nén ít nhất IDAT trước khi bạn có thể bắt đầu thực hiện bất cứ điều gì khác và về cơ bản sẽ giải mã toàn bộ hình ảnh.

Trong giày của bạn, tôi sẽ cố gắng để có một máy chủ làm điều đó cho tôi. Bạn chụp ảnh ở đâu? Không phải từ một máy chủ? Sau đó thử tạo một yêu cầu WS để cung cấp cho bạn phần thích hợp của hình ảnh. Nếu hình ảnh không đến từ máy chủ, bạn vẫn có thể gửi nó đến máy chủ của bạn để lấy lại chỉ một phần của hình ảnh mà bạn muốn.

+0

Cám ơn câu trả lời của bạn. Những gì tôi đang cố gắng thực hiện là thực hiện một MultiTouchImageView và thats cho tải chỉ một phần của hình ảnh có thể nhìn thấy do vị trí zoom và di chuyển, cho phép tải hình ảnh lớn mà không làm giảm chất lượng và không có sự cố bộ nhớ. Làm thế nào tôi có thể làm điều đó? – Addev

+0

Trong trường hợp đó, tôi nghĩ những gì bạn đang cố gắng chỉ đơn thuần là không thể với những hạn chế của thiết bị di động: bạn không thể cung cấp cho người dùng trải nghiệm tốt mà không tải toàn bộ hình ảnh trong bộ nhớ và chỉ hiển thị phần mà bạn cần . Ngay cả khi bạn có thể tải chỉ là một phần của hình ảnh, bạn sẽ phải làm điều đó mỗi khi người dùng mở hoặc thu nhỏ một chút ... vì hoạt động sẽ chậm, trải nghiệm người dùng sẽ vẫn là bất ngờ. Cách duy nhất để làm điều này là đặt một số giới hạn trên về kích thước của hình ảnh. Nếu không, bạn chỉ không thể làm điều đó IMHO. –

+0

Hmmm những gì bạn nói là rất hợp lý nhưng làm thế nào để Thư viện của Android tải những hình ảnh lớn cho phép phóng to với cùng chất lượng? – Addev

2

Tôi nghĩ rằng bạn có thể sử dụng phương pháp BitmapFactory cho phép bạn chỉ định Rect mà bạn muốn giải mã.

public static Bitmap decodeStream (InputStream is, Rect outPadding, BitmapFactory.Options opts) 
+0

Mặt ngoài là một tham số đặt ra – Addev

+0

@Addev Tôi thực sự thú vị .. vì vậy bạn không nghĩ rằng chỉ có thể thực hiện một số rect của một bitmap trước khi nhập nó? :) –

+0

trong trường hợp nào outPadding được lấp đầy? khi nó là 9-patch? có những trường hợp nào khác không? Ngoài ra, ngay cả khi nó là 9-patch, nó có nghĩa là gì và những gì sẽ được lấp đầy? –

0

thử mã này:

private Bitmap decodeFile(File f) { 
    Bitmap b = null; 
    try { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     FileInputStream fis = new FileInputStream(f); 
     b=Bitmap.createBitmap(BitmapFactory.decodeStream(fis, null, o), 100, 200, 200, 400, null, null); 
     fis.close(); 
    } catch (IOException e) { 
    } 
    return b; 
} 

Am không chắc chắn, nhưng điều này có thể đưa ra một số ý tưởng để bạn

+0

Nó đưa ra một lỗi bộ nhớ vì BitmapFactory.decodeStream (fis, null, o) không trả lại cho đến khi toàn bộ Bitmap được lấy ra – Addev

4

Nó có thể dễ dàng được thực hiện bằng RapidDecoder.

Tôi thực sự đã tạo ra kích thước tệp 9000x9000 png có kích thước khoảng 80MB và vùng có kích thước 200x400 được tải thành công.

import rapid.decoder.BitmapDecoder; 

Bitmap bitmap = BitmapDecoder.from("big-image.png") 
          .region(145, 192, 145 + 200, 192 + 400) 
          .decode(); 
imageView.setImageBitmap(bitmap); 

Nó hoạt động cho Android 2.2 trở lên.

+0

Ồ, điều này nghe có vẻ đầy hứa hẹn. không giải mã toàn bộ được thực hiện trên JNI? định dạng tệp nào được hỗ trợ? nó có hỗ trợ WebP không? nó có bao gồm phát hiện khuôn mặt không? –

+0

+1 thư viện rất tốt, chất lượng hình ảnh cũng được duy trì 80% .. và hoạt động trên hầu hết các thiết bị –

1

Hãy thử mã này:

public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(path, options); 

     final int height = options.outHeight; 
     final int width = options.outWidth; 
     options.inPreferredConfig = Bitmap.Config.RGB_565; 
     int inSampleSize = 1; 
     if (height > reqHeight) { 
      inSampleSize = Math.round((float) height/(float) reqHeight); 
     } 
     int expectedWidth = width/inSampleSize; 
     if (expectedWidth > reqWidth) { 
      inSampleSize = Math.round((float) width/(float) reqWidth); 
     } 
     options.inSampleSize = inSampleSize; 
     options.inJustDecodeBounds = false; 
     return BitmapFactory.decodeFile(path, options); 
    } 
Các vấn đề liên quan