2011-01-28 31 views
20

Nhờ Schermvlieger cho hỏi this câu hỏi về anddev.org,sử dụng tối ưu của BitmapFactory.Options.inSampleSize cho tốc độ

Tôi chỉ cần sao chép câu hỏi của mình để SO như không ai trả lời bên kia trang web và tôi cũng phải đối mặt với cùng một vấn đề.

Tôi đã tự hỏi điều gì sẽ là việc sử dụng tối ưu BitmapFactory.Options.inSampleSize liên quan đến tốc độ hiển thị hình ảnh.
Các tài liệu đề cập đến sử dụng các giá trị mà là một sức mạnh của 2, vì vậy tôi đang làm việc với 2, 4, 8, 16, vv

Những điều tôi đang tự hỏi về là:

  1. Tôi có nên Resample xuống đến kích thước nhỏ nhất vẫn lớn hơn độ phân giải màn hình, hoặc tôi có nên lấy mẫu xuống kích thước vừa đủ để tránh OutOfMemoryError không?
  2. Làm cách nào để tính toán kích thước tối đa của hình ảnh vẫn có thể được hiển thị mà không cần hết bộ nhớ? Độ sâu màu của hình ảnh có đóng vai trò tốt và độ sâu của màn hình không?
  3. Có hiệu quả khi hiển thị hình ảnh qua hai cơ chế (BitmapFactory đối với các tệp lớn, setImageURI() đối với các tệp nhỏ hơn). Tôi đang sử dụng ImageSwitcher bằng cách này.
  4. Có thể giúp tạo các số Bitmap, BitmapFactory.OptionsinTempStorage khi bắt đầu ứng dụng hoặc chỉ tạo chúng khi đang cần thiết không?

Trả lời

11

Bạn luôn phải cố tải và định tỷ lệ hình ảnh sao cho chúng càng gần với kích thước được hiển thị cuối cùng của chúng. Chia tỷ lệ hình ảnh tại thời điểm vẽ là cực kỳ tốn kém và nên tránh bằng mọi giá.

Xem xét chi phí bộ nhớ của hình ảnh, có, ngăn màu có vai trò rất quan trọng. Hình ảnh ở định dạng ALPHA_8 sử dụng 1 byte cho mỗi pixel, hình ảnh trong RGB_565 hoặc ARGB_4444 sử dụng 2 byte cho mỗi pixel và hình ảnh trong ARGB_8888 sử dụng 4 byte cho mỗi pixel. Độ sâu của màn hình không quan trọng chút nào. Bạn nên luôn cố gắng sử dụng ARGB_8888 để có được chất lượng tốt nhất có thể, nhưng 565 có thể đủ tốt nếu hình ảnh của bạn mờ đục.

+0

Khi bạn nói rằng "tỷ lệ hình ảnh ở thời gian vẽ cực kỳ đắt", điều này bao gồm các tùy chọn.inSampleSize cũng có? – kape123

+0

inSampleSize được sử dụng để chia tỷ lệ hình ảnh tại thời điểm tải, không phải lúc vẽ. Nó là một cách rất tốt để prescale hình ảnh. –

+1

Chúng tôi đang sử dụng ARGB_8888, sản xuất một hình ảnh rất mờ trên Samsung Galaxy Note 2, nhưng nó hoạt động tốt trên thiết bị khác, mang nó lên ARGB_4444 đang gặp lỗi ứng dụng trên Samsung Galaxy Note 2 và Pad 3110, do outOfMemoryError. Bạn có thể giúp chúng tôi phân loại điều này không. –

3

Ở đây bạn có thể gọi phương thức do người dùng xác định shrinkmehtod thực sự gửi đường dẫn tệp chuỗi và chiều cao và chiều rộng để giảm hình ảnh thành phương thức.

Bitmap bit=shrinkmethod(arrpath1[position], 100, 100); 


      //iv.setImageURI(Uri.parse(arrpath1[position])); 
      iv.setImageBitmap(bit); 

Đây là phương pháp do người dùng xác định để giảm kích thước hình ảnh theo chương trình.

Bitmap shrinkmethod(String file,int width,int height){ 
     BitmapFactory.Options bitopt=new BitmapFactory.Options(); 
     bitopt.inJustDecodeBounds=true; 
     Bitmap bit=BitmapFactory.decodeFile(file, bitopt); 

     int h=(int) Math.ceil(bitopt.outHeight/(float)height); 
     int w=(int) Math.ceil(bitopt.outWidth/(float)width); 

     if(h>1 || w>1){ 
      if(h>w){ 
       bitopt.inSampleSize=h; 

      }else{ 
       bitopt.inSampleSize=w; 
      } 
     } 
     bitopt.inJustDecodeBounds=false; 
     bit=BitmapFactory.decodeFile(file, bitopt); 



     return bit; 

    } 

Tôi hy vọng điều này sẽ giúp bạn giảm kích thước.

+2

Orginally từ đây http://madhusudhanrc.blogspot.fr/2012/09/reduce-bitmap-size-using.html – Snicolas

4

Bạn đã đặt câu hỏi hay, nhưng tất cả đều tùy thuộc vào nhu cầu của bạn và lượng bộ nhớ bạn sử dụng. Tôi khuyên bạn nên xem liên kết này để biết nhiều mẹo về bitmap: http://developer.android.com/training/displaying-bitmaps/index.html.

Tóm lại, bạn nên xem xét lưu vào bộ nhớ đệm, định dạng phông và sử dụng định dạng bitmap đủ tốt bất cứ khi nào bạn có thể.

Dưới đây là câu trả lời của tôi cho câu hỏi của bạn:

  1. Tại sao không phải cả hai? nếu bạn nghĩ rằng có thể có OOM, hãy thử tái chế các bitmap cũ, không sử dụng và sau đó kiểm tra lại.

  2. bạn có thể tính toán (ước tính) kích thước của bitmap:

    chiều rộng * chiều cao * bytesPerPixel

    nơi bytesPerPixel thường là 4 hoặc 2 (tùy theo định dạng bitmap).

  3. Không bao giờ được sử dụng setImageURI, vì vậy tôi không thể giúp bạn với điều đó. Tôi đề nghị tải hình ảnh trong một chủ đề nền (sử dụng asyncTask là một cách để làm như vậy) và hiển thị chúng khi nó đã sẵn sàng.

  4. Nếu chỉ có một số ít bạn biết rằng sẽ không mất nhiều bộ nhớ, tôi đoán nó là ok. Tôi vẫn nghĩ rằng bộ nhớ đệm có thể tốt hơn.

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