2011-06-29 55 views
27

Tôi dự định hiển thị Hình ảnh rất lớn trong Android.

Giải pháp đầu tiên của tôi - để cung cấp chúng dưới dạng pdf - không thành công vì không phải mọi thiết bị cầm tay đều được cài đặt sẵn trình xem pdf và tôi không muốn yêu cầu người dùng cài đặt.hiển thị hình ảnh lớn trong Android

Vì vậy, tôi có một png bây giờ (chiều rộng = 3998px chiều cao = 2827px) mà tôi muốn hiển thị. Tôi đã tải xuống hình ảnh này để kiểm tra xem nó sẽ được hiển thị như thế nào. Nó khá đau đớn. Có vẻ như galery chỉ hiển thị hình ảnh này một lần, và nếu tôi phóng to, tôi không thể đọc được văn bản nào cả.

Vì vậy, tôi đã viết một testActivity mà chỉ đơn giản là có một ImageView lồng nhau trong một LinearLayout. Tôi đưa hình ảnh vào hình vẽ và đặt nó làm hình ảnh của ImageView. Unforunately ứng dụng bị treo immediatly, do một "

ERROR/AndroidRuntime(8906): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget" 

Tôi không ngờ rằng ONE đơn Hình ảnh có thể quá lớn đối với VM's memory. Tôi đã chơi một chút xung quanh, thiết lập kích thước ImageViews-3998 & 2827px, đặt hình ảnh để sdCard và đọc nó bằng tay với một fileInputStream.
trước sự ngạc nhiên lớn của tôi bây giờ cho thấy hình ảnh của tôi, nhưng nếu tôi biến tôi Nexus S ngang tôi nhận được cùng một OutOfMemoryError như trước đây.

thể somewone chỉ cho tôi những khác biệt chính giữa rec ieving một Bitmap thông qua một FileInputStream hoặc để đặt nó là ImageView's nguồn.

Ngoài ra tôi không thể di chuyển thoải mái với hai mẹ scrollViews

Tôi tìm kiếm một giải pháp đơn giản để hiển thị ONE large image tại một thời điểm với khả năng scroll horizontal and vertical trong khi có thể phóng to trong và ngoài.

đây là một ví dụ về các hình ảnh tôi muốn hiển thị enter image description here

Trả lời

26

Tôi biết đó là một bài đăng cũ nhưng tôi đã dành rất nhiều thời gian cho vấn đề này, vì vậy đây là giải pháp của tôi.

Tôi muốn hiển thị hình ảnh 2000 × 3000 nhưng tôi đã hết bộ nhớ hoặc hình ảnh quá lớn để hiển thị.

Để bắt đầu, tôi nhận được kích thước của hình ảnh:

o = new BitmapFactory.Options(); 
o.inJustDecodeBounds=true; 
pictures = BitmapFactory.decodeStream(new FileInputStream(f), null, o); 

Sau đó, tôi cắt nó ra thành bốn phần và hiển thị chúng với bốn ImageViews. Tôi đã cố gắng tải hình ảnh đầy đủ và cắt nó thành bốn (sử dụng BitmapFactory.create(bitmap,int,int,int,int)) nhưng đã hết bộ nhớ.

Vì vậy, tôi quyết định sử dụng một số BitMapRegionDecoder:

for (int i = 0; i < 2; i++) { 
    for (int j = 0; j < 2; j++) { 
     ImageView iv = new ImageView(this);   
     InputStream istream = null; 
     try { 
     istream = this.getContentResolver().openInputStream(Uri.fromFile(f)); 
     } catch (FileNotFoundException e1) { 
     e1.printStackTrace(); 
     } 
     BitmapRegionDecoder decoder  = null; 
     try { 
     decoder = BitmapRegionDecoder.newInstance(istream, false); 
     } catch (IOException e) { 
        e.printStackTrace(); 
     } 
    int nw = (j*width/k); 
    int nh = (i*height/k); 

    Bitmap bMap = decoder.decodeRegion(new Rect(nw,nh, (nw+width/k),(nh+height/k)), null);  
    iv.setImageBitmap(bMap); 

    } 
} 

này làm việc.

+0

Giải pháp tốt. Bây giờ tôi đã tìm thấy một cách tốt hơn nữa (với nhiều nỗ lực mã hóa) bằng cách vẽ hình ảnh của tôi. Tôi cũng có 3 phiên bản của cùng một hình ảnh với chất lượng khác nhau cho các ZoomLevel khác nhau. Điều này sẽ làm việc ngay cả trên các thiết bị cũ, không thể giải mã 1/4 của Bitmap gốc –

+2

** k ** ở đây là gì? Hy vọng ** chiều rộng ** và ** chiều cao ** có nghĩa là kích thước hình ảnh thực tế. Hãy làm rõ điều đó. – AnujAroshA

+1

Rafael: Bạn không nên (theo lý thuyết!) Cần các phiên bản có độ phân giải khác nhau - hãy kiểm tra 'BitmapFactory.Options.inSampleSize'. – Timmmm

1

Câu trả lời này nên giải quyết nó cho u Strange out of memory issue while loading an image to a Bitmap object

+0

nhờ liên kết đó, tôi không thấy chủ đề này. Sự kết hợp của các giải pháp này đã khắc phục lỗi OOM trong ứng dụng của tôi. Rất tiếc, không ai chỉ ra cách Phóng to Chế độ xem hình ảnh tùy chỉnh. Nếu tôi sửa nó, tôi đăng giải pháp của tôi ở đây. –

2

This post là một bản demo tốt cho phóng to ảnh bằng cử chỉ cảm ứng đa. Nó sử dụng ma trận để phóng to cũng như xoay một bức tranh.

4

Bạn có thể sử dụng "dễ integerate" nguồn gốc của ứng dụng WorldMap:

https://github.com/johnnylambada/WorldMap

Điều này sử dụng hình ảnh khổng lồ của bản đồ thế giới và sử dụng bộ nhớ cache để hiển thị bản đồ.

Để tích hợp, tôi chỉ sao chép tất cả các tệp java (5 tôi đoán) và sử dụng SurfaceView trong tệp bố cục của tôi. Sau đó, tôi đã đi qua phương thức OnCreate() nhỏ của ImageViewerActivity.java và sử dụng mã trong hoạt động của tôi (với thay đổi sligh, tùy thuộc vào việc sử dụng cá nhân của tôi).

1

Để xử lý mở rộng vv và sử dụng độ phân giải đầy đủ, bạn có thể sử dụng MapView của OSM (bản đồ đường phố mở) và cung cấp nó với các ô xếp của bạn (thay vì bản đồ). Kiểm tra này: http://www.haakseth.com/?p=30

7

Cố gắng sử dụng này một: https://github.com/davemorrissey/subsampling-scale-image-view

Một cái nhìn hình ảnh tùy chỉnh cho Android, được thiết kế cho bộ sưu tập ảnh và hiển thị hình ảnh lớn (ví dụ như bản đồ và kế hoạch xây dựng) không có OutOfMemoryErrors. Bao gồm chụm để thu phóng, xoay, xoay và hỗ trợ hoạt ảnh và cho phép tiện ích mở rộng dễ dàng để bạn có thể thêm các lớp phủ và phát hiện sự kiện chạm của riêng mình.

+0

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. – Kmeixner

+0

Nhưng thư viện này không thể xoay hình ảnh bằng các thao tác chạm, nó chỉ cho phép xoay 90 độ. – bebosh

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