如何在android中计算自定义相机中的剩余照片数量

Posted

技术标签:

【中文标题】如何在android中计算自定义相机中的剩余照片数量【英文标题】:How to calculate remaining photos counts in custom camera in android 【发布时间】:2018-02-23 19:46:42 【问题描述】:

我正在尝试计算可以使用我的自定义相机拍摄的剩余照片数量,并将该数量显示给用户。我尝试使用以下代码:

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

获取分辨率的方法。

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;
    

问题: 手机相机中显示的计数和我的应用中显示的计数有很大差异。

那么正确的做法是什么?

注意:我只会以最高质量捕捉图像。因此,我只根据一种分辨率计算计数。

【问题讨论】:

为什么你会假设一张照片是 7MB?这些是压缩文件。根据实际捕获的数据,它可能会少得多或多得多。这是假设您没有达到特定于供应商的每个应用程序的最大存储限制。而且您假设所有相机都以相同的分辨率拍摄照片,但事实并非如此。 这就是为什么我要问什么是进行计算的正确方法。我知道上面的代码不适用于其他设备。 @GabeSechan 现在检查。我现在使用动态方法进行计算。 我还开发了一个自定义相机,并会朝着这个方向发展:当应用程序启动时,我会假设照片文件大约需要 4(5?6?)MB - 不管怎样,让用户知道在这种情况下,还有许多图像。同时,我将启动一个低优先级线程,该线程创建一个具有随机颜色像素的位图,具有图像的分辨率,将其写入文件系统并读取其实际大小。在此之后,我将为用户更新剩余图像的数量。如果你想更精确,在应用运行过程中考虑新文件。 【参考方案1】:

无法找到用于 JPEG/PNG 压缩的输出图像的确切尺寸。压缩算法经过优化,使其使用尽可能小的尺寸,但保留图像像素(尽管 JPEG 有轻微的有损)。

但是,您可以通过拍摄多张样本照片并计算平均压缩率来估算图像数量。

来自Wikipedia:

JPEG 通常可实现 10:1 压缩,而图像质量几乎没有明显损失。

所以估计的存储大小可以计算为:

int bytes = width * height * 2 / compressionRatio;

这里乘以 2,因为在 RGB_565 配置中,它需要 2 个字节来存储 1 个像素。

【讨论】:

如何获得压缩比。我认为从电话到电话会过于谨慎 是的,它会因手机而异,这就是您应该考虑平均值的原因。不仅从手机到手机,即使在一部手机中,它也因照片而异。您可以计算多个样本的压缩率并将它们平均,或者在谷歌中搜索其他的结果。 如何以编程方式从照片中获取压缩率? 您计算压缩率和字节数的公式在结果中给出了非常大的数字。我有 3744X5376 分辨率的图像。 是的,它会很大,因为它以字节为单位。使用这个公式:float compressionRatio = (width * height * 2) / fileSizeInBytes;【参考方案2】:

我认为留下的图像没有最终的解决方案,因为有太多不同的设备和相机,而且它在很大程度上取决于图像内容。

我找到了一个很好的解释here

如前所述,您可以根据设备可用空间预测图像大小并计算剩余图像数。要获得该预测,最佳解决方案是首先在您的设备上进行尝试。 用户开始使用该应用程序后,您可以将他最近 10 张照片尺寸包括在计算中。 如果它不是关键特性,您可以将其作为基于使用情况的预测来呈现,而不是作为具有约束力的事实。

附言 我使用的是三星 Galaxy S7 edge,相机中根本没有剩余图像。 (或者我只是找不到它)

【讨论】:

【参考方案3】:

经过大量的研究和谷歌搜索,我来到了this 网站。

根据本网站,以下是获取文件大小的步骤。

    将检测器的水平像素数乘以垂直像素数得到检测器的总像素数。 将总像素数乘以检测器的位深度(16 位、14 位等)得到数据的总位数。 总位数除以 8 等于文件大小(以字节为单位)。 将字节数除以 1024 得到文件大小(以千字节为单位)。再次除以 1024 得到文件大小(以兆字节为单位)。

因此,当我按照上述步骤操作时,即我的探测器分辨率为 5376X3024。 继续执行上述步骤,我最终得到 39 MB 作为图像大小的答案。

但是相机拍摄的图像大小约为 8-10 MB,与我在上面得到的结果仍然不接近。

我的手机 (HTC Desire 10 pro) 有一个可用的专业模式设置。在此模式下,照片将被捕获为原始图像。所以当我检查捕获的原始图像的大小时,我很高兴原始文件的大小确实在 39 MB 左右,这表明上述步骤对于计算图像的原始大小是正确的。

结论

通过以上步骤,我得出的结论是手机软件确实使用了一些压缩算法来缩小图像大小。所以我比较的是实际压缩的图像,因此图像的数量是不同的。

可能的解决方案

我现在的目标是从我的相机中获取最后点击的图像,获取其文件大小并根据该文件大小显示计数。这也是一个近似结果,但我认为没有任何解决方案可以得到准确的计数。

这是我用来实现上述解决方案的代码

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


【讨论】:

当然JPEG文件是压缩的。您可以通过 setJpegQuality(int) 方法指定压缩级别。我通常在 70-90 范围内使用它来保持高质量的图像,同时大大减小它们的大小。 @rommex 不明白您的评论是什么意思? 基本上,我是说如果您使用非原始格式,您无法预测图像文件的大小。此类格式使用压缩。【参考方案4】:

我认为您可以检查 DCIM 目录(默认摄像机目录)中的文件数并计算所有文件的大小,然后通过除以文件数得到平均大小。

你会得到平均尺寸的相机正在捕捉图像 在 Asynctask 中执行上述步骤。

并且您已经计算了剩余大小(以字节为单位),现在再次将剩余大小除以平均大小,您将获得大约可以捕获的图像数量。

【讨论】:

以上是关于如何在android中计算自定义相机中的剩余照片数量的主要内容,如果未能解决你的问题,请参考以下文章

如何在科尔多瓦相机中保存自定义名称的照片

Android7.0调用系统相机拍照读取系统相册照片+CropImageView剪裁照片

带有圆形边框的Android自定义相机

Android笔记67Android之使用系统中的相机功能(拍照保存照片显示拍摄的照片照片保存到图库等操作)

如何在android中设置相机预览的大小

android 客户端开发 如何同时上传多张照片