2017-09-14 16 views
8

Tôi đang cố gắng tính số lượng ảnh còn lại có thể chụp bằng máy ảnh tùy chỉnh của tôi và hiển thị số đó cho người dùng. Tôi đã thử với mã sau:Cách tính số ảnh còn lại trong máy ảnh tùy chỉnh trong android

private void numberOfPhotosAvailable() { 
     long photosAvailable = 0; 
     StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); 
     resolution=getResolution(); 
     long bytesPerPhoto=resolution/1048576; 
     long bytesAvailable = (long) stat.getAvailableBlocksLong() * (long) stat.getBlockSizeLong(); 
     long megAvailable = bytesAvailable/1048576; 

     System.out.println("Megs :" + megAvailable); 
     photosAvailable = megAvailable/bytesPerPhoto; 
     tvAvailablePhotos.setText("" + photosAvailable); 
    } 

Phương pháp để nhận được giải pháp.

public long getResolution(){ 
     long resolution=0; 
     Camera.Parameters params=mCamera.getParameters(); 
     List<Camera.Size> sizes = params.getSupportedPictureSizes(); 

     Camera.Size size = sizes.get(0); 
     int width=size.width; 
     int height=size.height; 
     resolution=width*height; 
     return resolution; 
    } 

VẤN ĐỀ: Có rất nhiều sự khác biệt về số lượng thể hiện trong máy ảnh của điện thoại và đếm được hiển thị trong ứng dụng của tôi.

Vì vậy, cách thích hợp để thực hiện việc này là gì?

LƯU Ý: Tôi sẽ chỉ chụp hình ở chất lượng cao nhất hiện có. Do đó tôi chỉ tính đếm theo một độ phân giải duy nhất.

+0

Tại sao bạn cho rằng ảnh sẽ là 7MB? Đó là những tập tin nén. Tùy thuộc vào dữ liệu thực sự nắm bắt nó có thể là ít hơn hoặc nhiều hơn nữa. Và đó là giả sử bạn không đạt đến giới hạn của nhà cung cấp cụ thể cho mỗi giới hạn dung lượng lưu trữ tối đa của ứng dụng. Và bạn giả định rằng tất cả các máy ảnh chụp ảnh ở cùng độ phân giải, không phải như vậy. –

+0

Đó là lý do tại sao tôi hỏi cách chính xác để thực hiện phép tính là gì. Tôi biết mã trên sẽ không hoạt động đối với các thiết bị khác. –

+0

@GabeSechan hiện kiểm tra. Tôi hiện đang sử dụng một cách tiếp cận năng động để tính toán. –

Trả lời

2

Sau rất nhiều nghiên cứu và googling, tôi đã đến trang this.

Theo trang web này, sau đây là các bước để lấy kích thước tệp.

  1. Nhân dò số lượng điểm ảnh ngang theo số pixel dọc để nhận tổng số pixel của máy dò.
  2. Nhân tổng số pixel theo độ sâu bit của máy dò (16 bit, 14 bit, v.v.) để nhận tổng số bit dữ liệu.
  3. Chia tổng số bit bằng 8 bằng kích thước tệp theo byte.
  4. Chia số byte theo 1024 để nhận kích thước tệp tính bằng kilobyte. Chia nhỏ lại 1024 lần và nhận kích thước tệp theo megabyte.

Vì vậy, khi tôi làm theo các bước trên, tức là độ phân giải của máy dò là 5376X3024. Tiếp tục với các bước trên, cuối cùng tôi đã nhận được 39 MB làm câu trả lời cho kích thước hình ảnh.

Nhưng hình ảnh được chụp bởi máy ảnh có kích thước khoảng 8-10 MB nhưng vẫn không gần với kết quả tôi nhận được ở trên.

Điện thoại của tôi (HTC Desire 10 pro) có cài đặt chế độ chuyên nghiệp khả dụng. Trong chế độ này, ảnh được chụp dưới dạng ảnh thô. Vì vậy, khi tôi kiểm tra kích thước của hình ảnh thô đã chụp, tôi đã thích thú vì kích thước của tệp thô thực sự là khoảng 39 MB, cho biết các bước trên là chính xác để tính kích thước ban đầu của hình ảnh.

KẾT LUẬN

Với các bước trên tôi đi đến kết luận rằng phần mềm của điện thoại thực sự sử dụng một số thuật toán nén để làm kích thước hình ảnh ít hơn. Vì vậy, những gì tôi đã so sánh với thực sự là hình ảnh nén do đó số lượng hình ảnh là khác nhau.

có thể xảy ra SOLUTION

Phương pháp mà tôi bây giờ mục tiêu là để có được hình ảnh nhấp cuối cùng từ máy ảnh của tôi, có kích thước tập tin của nó và hiển thị đếm theo kích thước tập tin. Đây cũng sẽ là một kết quả gần đúng nhưng tôi không nghĩ rằng có thể có bất kỳ giải pháp nào để nhận được số lượng chính xác.

Đây là mã tôi đang sử dụng để thực hiện các giải pháp trên

private void numberOfPhotosAvailable() { 
    long photosAvailable = 0; 
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath()); 
    File lastFile=null; 
    lastFile=utils.getLatestFilefromDir(prefManager.getString(PrefrenceConstants.STORAGE_PATH)); 
    if (lastFile!=null){ 
     double fileSize=(lastFile.length())/(1024*1024); 
     long bytesAvailable = (long) stat.getAvailableBlocksLong() * (long) stat.getBlockSizeLong(); 
     long megAvailable = bytesAvailable/1048576; 

     System.out.println("Megs :" + megAvailable); 
     photosAvailable = (long) (megAvailable/fileSize); 
     tvAvailablePhotos.setText("" + photosAvailable); 
    }else{ 
     tvAvailablePhotos.setVisibility(View.INVISIBLE); 
    } 

} 
+0

Tất nhiên các tệp JPEG được nén. Bạn chỉ định mức độ nén theo phương thức setJpegQuality (int). Tôi thường sử dụng nó trong khoảng 70-90 để giữ chất lượng hình ảnh cao trong khi giảm đáng kể kích thước của chúng. – rommex

+0

@rommex không hiểu ý bạn là gì? –

+0

Về cơ bản, tôi đã nói rằng bạn _cannot_ dự đoán kích thước của tệp hình ảnh nếu bạn đang sử dụng định dạng không phải thô. Các định dạng như vậy sử dụng nén. – rommex

5

Không thể tìm thấy kích thước chính xác của hình ảnh đầu ra để nén JPEG/PNG. Các thuật toán nén được tối ưu hóa theo cách mà chúng sử dụng càng ít kích thước càng tốt nhưng vẫn giữ nguyên điểm ảnh (mặc dù JPEG hơi bị mất).

Tuy nhiên, bạn có thể ước tính không có hình ảnh bằng cách chụp nhiều ảnh mẫu và tính tỷ lệ nén trung bình.

Từ Wikipedia:

JPEG thường đạt 10: 1 nén với chút mất cảm nhận được chất lượng hình ảnh.

Vì vậy, ước tính kích thước lưu trữ có thể được tính như sau:

int bytes = width * height * 2/compressionRatio; 

Ở đây nó được nhân với 2 bởi vì trong RGB_565 config, nó đòi hỏi 2 byte để lưu trữ 1 pixel.

+0

Cách tôi nhận được tỷ lệ nén. Tôi nghĩ rằng nó sẽ quá thận trọng từ điện thoại đến điện thoại –

+0

Có nó sẽ thay đổi từ điện thoại đến điện thoại, đó là lý do tại sao bạn nên xem xét một giá trị trung bình. Không chỉ từ điện thoại đến điện thoại, nó cũng thay đổi từ ảnh này sang ảnh khác ngay cả trong một điện thoại. Bạn có thể tính toán tỷ lệ nén cho nhiều mẫu và trung bình chúng hoặc tìm kiếm kết quả của người khác trong google. –

+0

Làm thế nào để tôi có được tỷ lệ nén từ ảnh lập trình? –

2

Tôi nghĩ rằng không có giải pháp tối ưu cho hình ảnh còn lại vì có quá nhiều thiết bị và máy ảnh khác nhau và cũng phụ thuộc rất nhiều vào nội dung hình ảnh.

Một cách giải thích tốt cho điều đó tôi đã tìm thấy here

Như đã đề cập trước khi bạn có thể dự đoán kích thước hình ảnh và tính toán hình ảnh đếm lại dựa trên một thiết bị không gian trống. Để có được giải pháp tốt nhất tiên đoán đó là hãy thử nó trên thiết bị của bạn trước tiên. Sau khi người dùng bắt đầu sử dụng ứng dụng, bạn có thể bao gồm 10 kích thước ảnh cuối cùng của mình trong tính toán. Nếu nó không phải là một tính năng chính bạn chỉ có thể trình bày nó như là dự đoán dựa trên cách sử dụng, không phải là một thực tế ràng buộc.

P.S Tôi đang sử dụng cạnh Samsung Galaxy S7 và không có hình ảnh nào còn lại được tính trong máy ảnh. (Hoặc tôi không thể tìm thấy nó)

1

Tôi nghĩ rằng bạn có thể kiểm tra thư mục DCIM (Mặc định Máy ảnh Directory) cho số lượng tập tin và tính toán kích thước của tất cả các tập tin và lấy kích thước trung bình bằng cách chia số lượng tệp.

và bạn sẽ nhận được máy ảnh kích thước trung bình đang chụp hình ảnh thực hiện các bước trên trong Asynctask.

và bạn đã tính toán kích thước còn lại tính theo byte hiện chia lại kích thước còn lại với kích thước trung bình và bạn sẽ nhận được số lượng ảnh bạn có thể chụp.

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