android 如何计算自定义相机中的剩余照片数
How to calculate remaining photos counts in custom camera in 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);
}
获取分辨率的方法。
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;
}
问题:
phone 的相机中显示的计数与我的应用程序中显示的计数有很大差异。
那么正确的做法是什么?
注意:我只会以可用的最高质量拍摄图像。因此我只根据一种分辨率计算计数。
无法找到 JPEG/PNG 压缩输出图像的确切大小。压缩算法以这样一种方式进行了优化,即它们使用尽可能小的尺寸但保留图像像素(尽管 JPEG 略有损耗)。
不过,您可以通过拍摄多张样本照片并计算平均压缩率来估计图像数量。
来自Wikipedia:
JPEG typically achieves 10:1 compression with little perceptible loss in image quality.
因此估计的存储大小可以计算为:
int bytes = width * height * 2 / compressionRatio;
这里乘以2,因为在RGB_565配置中,需要2个字节来存储1个像素。
我认为留图没有最终的解决方案,因为设备和相机太多了,而且对图片内容的依赖也很大。
我找到了一个很好的解释 here
按照之前的建议,您可以预测图像大小并根据设备空闲 space 计算剩余图像数。要获得该预测,最好的解决方案是先在您的设备上进行尝试。
用户开始使用该应用程序后,您可以将他最近 10 张照片的尺寸计算在内。
如果它不是关键功能,您可以将其作为基于使用情况的预测来呈现,而不是作为具有约束力的事实。
P.S
我使用的是 Samsung Galaxy S7 edge,相机中根本没有剩余图像。 (或者我就是找不到)
经过大量研究和谷歌搜索,我来到了 this 网站。
根据此站点,以下是获取文件大小的步骤。
- 将探测器的水平像素数乘以垂直像素数得到探测器的总像素数。
- 将像素总数乘以检测器的位深度(16位、14位等)得到数据的总位数。
- 总位数除以 8 等于文件大小(以字节为单位)。
- 将字节数除以 1024 得到以千字节为单位的文件大小。再次除以 1024 并得到以兆字节为单位的文件大小。
因此,当我按照上述步骤操作时,即我的检测器分辨率为 5376X3024。 继续上述步骤,我最终得到 39 MB 作为图像大小的答案。
但是相机拍摄的图像大小约为 8-10 MB,与我上面得到的结果还差得很远。
我的 phone (HTC Desire 10 pro) 有可用的专业模式设置。在这种模式下,照片被捕获为原始图像。所以当我检查捕获的原始图像的大小时,我被逗乐了,因为原始文件的大小确实在 39 MB 左右,这表明上述步骤对于计算图像的原始大小是正确的。
结论
通过以上步骤我得出的结论是phone的软件确实使用了一些压缩算法来缩小图像尺寸。所以我比较的实际上是压缩图像,因此图像数量不同。
可能的解决方案
我现在的目标是从我的相机中获取最后点击的图像,获取其文件大小并根据该文件大小显示计数。这也将是一个近似结果,但我认为没有任何解决方案可以获得准确的计数。
这是我用来实现上述解决方案的代码
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);
}
}
我想你可以查看DCIM目录(默认相机目录)的文件数量,计算所有文件的大小,然后用文件数量除以平均大小。
你会得到平均大小的相机正在捕捉图像
在 Asynctask 中执行上述步骤。
并且您已经计算了剩余大小(以字节为单位),现在再次将剩余大小除以平均大小,您将得到可以捕获的大约图像数。
我正在尝试计算可以使用我的自定义相机拍摄的剩余照片数量,并将该计数显示给用户。我尝试使用以下代码:
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;
}
问题: phone 的相机中显示的计数与我的应用程序中显示的计数有很大差异。
那么正确的做法是什么?
注意:我只会以可用的最高质量拍摄图像。因此我只根据一种分辨率计算计数。
无法找到 JPEG/PNG 压缩输出图像的确切大小。压缩算法以这样一种方式进行了优化,即它们使用尽可能小的尺寸但保留图像像素(尽管 JPEG 略有损耗)。
不过,您可以通过拍摄多张样本照片并计算平均压缩率来估计图像数量。
来自Wikipedia:
JPEG typically achieves 10:1 compression with little perceptible loss in image quality.
因此估计的存储大小可以计算为:
int bytes = width * height * 2 / compressionRatio;
这里乘以2,因为在RGB_565配置中,需要2个字节来存储1个像素。
我认为留图没有最终的解决方案,因为设备和相机太多了,而且对图片内容的依赖也很大。
我找到了一个很好的解释 here
按照之前的建议,您可以预测图像大小并根据设备空闲 space 计算剩余图像数。要获得该预测,最好的解决方案是先在您的设备上进行尝试。 用户开始使用该应用程序后,您可以将他最近 10 张照片的尺寸计算在内。 如果它不是关键功能,您可以将其作为基于使用情况的预测来呈现,而不是作为具有约束力的事实。
P.S 我使用的是 Samsung Galaxy S7 edge,相机中根本没有剩余图像。 (或者我就是找不到)
经过大量研究和谷歌搜索,我来到了 this 网站。
根据此站点,以下是获取文件大小的步骤。
- 将探测器的水平像素数乘以垂直像素数得到探测器的总像素数。
- 将像素总数乘以检测器的位深度(16位、14位等)得到数据的总位数。
- 总位数除以 8 等于文件大小(以字节为单位)。
- 将字节数除以 1024 得到以千字节为单位的文件大小。再次除以 1024 并得到以兆字节为单位的文件大小。
因此,当我按照上述步骤操作时,即我的检测器分辨率为 5376X3024。 继续上述步骤,我最终得到 39 MB 作为图像大小的答案。
但是相机拍摄的图像大小约为 8-10 MB,与我上面得到的结果还差得很远。
我的 phone (HTC Desire 10 pro) 有可用的专业模式设置。在这种模式下,照片被捕获为原始图像。所以当我检查捕获的原始图像的大小时,我被逗乐了,因为原始文件的大小确实在 39 MB 左右,这表明上述步骤对于计算图像的原始大小是正确的。
结论
通过以上步骤我得出的结论是phone的软件确实使用了一些压缩算法来缩小图像尺寸。所以我比较的实际上是压缩图像,因此图像数量不同。
可能的解决方案
我现在的目标是从我的相机中获取最后点击的图像,获取其文件大小并根据该文件大小显示计数。这也将是一个近似结果,但我认为没有任何解决方案可以获得准确的计数。
这是我用来实现上述解决方案的代码
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);
}
}
我想你可以查看DCIM目录(默认相机目录)的文件数量,计算所有文件的大小,然后用文件数量除以平均大小。
你会得到平均大小的相机正在捕捉图像 在 Asynctask 中执行上述步骤。
并且您已经计算了剩余大小(以字节为单位),现在再次将剩余大小除以平均大小,您将得到可以捕获的大约图像数。