Search code examples
androidimageandroid-cameraresolution

How to calculate remaining photos counts in custom camera in android


I'm trying to calculate the remaining number of photos that can be taken using my custom camera and show that count to the user. I tried with the following code:

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);
    }

Method for getting resolution.

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;
    }

PROBLEM: There is a lot of difference in the count shown in the phone's camera and count that is shown in my app.

So what is the proper way of doing this ?

NOTE: I will only be capturing image in the highest quality available. Therefore I am only calculating count according to one resolution only.


Solution

  • Well after lot of researching and googling, I came to this site.

    According to this site, following are the steps to get the file size.

    1. Multiply the detectors number of horizontal pixels by the number of vertical pixels to get the total number of pixels of the detector.
    2. Multiply total number of pixels by the bit depth of the detector (16 bit, 14 bit etc.) to get the total number of bits of data.
    3. Dividing the total number of bits by 8 equals the file size in bytes.
    4. Divide the number of bytes by 1024 to get the file size in kilobytes. Divide by 1024 again and get the file size in megabytes.

    So when I followed the above steps, i.e. my detectors resolution is 5376X3024. Proceeding with the above steps I finally got 39 MB as answer for image size.

    But the image taken by camera was around 8-10 MB in size which was still not close to what I got in result above.

    My phone (HTC Desire 10 pro) has a pro mode settings available. In this mode photos are captured as raw images. So when I checked for the size of the captured raw image, I was amused as the size of the raw file was indeed around 39 MB, which states that above steps are correct for calculating image's original size.

    CONCLUSION

    With the above steps I came to the conclusion that phone's softwares indeed use some compression algorithms to make image size less. So what I was comparing to was actually compressed images hence the count of images was different.

    PROBABLE SOLUTION

    The approach that I am now aiming is to get the last clicked image from my camera, get its file size and show count according to that file size. This will also be a approximate result but I don't think there can be any solution for getting exact count.

    This is the code I am using to implement the above solution

    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);
        }
    
    }