1、获取相机支持的预览和保存照片的尺寸
- 获取 mPreviewSizes 和 mPictureSizes 的代码
/**
* 打开摄像头
*/
private void openCamera() {
if (mCamera != null) {
releaseCamera();
}
mCamera = Camera.open(mCameraId);
mCameraParameters = mCamera.getParameters();
// Supported preview sizes
mPreviewSizes.clear();
for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()) {
mPreviewSizes.add(new Size(size.width, size.height));
}
// Supported picture sizes;
mPictureSizes.clear();
for (Camera.Size size : mCameraParameters.getSupportedPictureSizes()) {
mPictureSizes.add(new Size(size.width, size.height));
}
// AspectRatio
if (mAspectRatio == null) {
mAspectRatio = Constants.DEFAULT_ASPECT_RATIO;
}
adjustCameraParameters();
mCamera.setDisplayOrientation(calcDisplayOrientation(mDisplayOrientation));
mCallback.onCameraOpened();
if (null != mRecordVideoManager) {
mRecordVideoManager.onCameraOpened(mFacing);
}
}
- 某360手机支持的预览尺寸和保存尺寸,分组依据是宽高比,比如4:3和16:9
- 再来看某华为平板支持的预览尺寸和保存尺寸,分组依据是宽高比,比如4:3和16:9
说的这里就有个问题了,之前公司开发认为有个bug是这款华为平板拍照保存的照片尺寸太小,条件是分辨率≤1920 * 1080,但是他们限制了宽高比为4:3所以取到的只有value[1]的4个分辨率,符合条件的最大分辨率为640 * 480,导致照片不够清晰以及一些其他问题,后来把宽高比限制为4:3 or 16:9,就可以取到最符合的分辨率1920 * 1080了。
2、获取满足条件的预览和保存照片的尺寸
我们获取4:3 or 16:9的分辨率尺寸,我的最佳分辨率的算法是,在该设备下(屏幕固定),并限定宽高比的条件下,利用分辨率的面积(宽*高,可以理解为像素的个数)和目标的分辨率面积,进行比对差值最小的即为最佳分辨率。
//用来比对的绝对值
private int mPictureAbs = -1;
/**
* 设定相机相关参数,比如预览和保存的图片大小
*/
private void adjustCameraParameters() {
SortedSet<Size> previewSizes = new TreeSet<>();
SortedSet<Size> pictureSizes = new TreeSet<>();
AspectRatio aspectRatio4_3 = checkAspectRatio(Constants.DEFAULT_ASPECT_RATIO);
AspectRatio aspectRatio16_9 = checkAspectRatio(Constants.SECOND_ASPECT_RATIO);
//预览图片尺寸集合
previewSizes.addAll(mPreviewSizes.sizes(aspectRatio4_3));
previewSizes.addAll(mPreviewSizes.sizes(aspectRatio16_9));
//保存图片尺寸集合
pictureSizes.addAll(mPictureSizes.sizes(aspectRatio4_3));
pictureSizes.addAll(mPictureSizes.sizes(aspectRatio16_9));
//预览的尺寸集合,选择最佳的预览尺寸
Size previewSize = chooseOptimalSize(previewSizes);
// Always re-apply camera parameters
if (mShowingPreview) {
stopPreview();
}
Size pictureSize = pictureSizes.last();
if (null == mRecordVideoManager) {
for (Size tempSize : pictureSizes) {
//根据像素点(面积)计算最符合目标的分辨率
int referencePixels = MultiMediaConfig.MAX_PIC_WIDTH * MultiMediaConfig.MAX_PIC_HEIGHT;
int picturePixels = tempSize.getWidth() * tempSize.getHeight();
int abs = Math.abs(referencePixels - picturePixels);
if (mPictureAbs < 0 || mPictureAbs > abs) {
mPictureAbs = abs;
pictureSize = tempSize;
} else {
mPictureAbs = -1;
break;
}
}
mCameraParameters.setPictureFormat(ImageFormat.JPEG);
mCameraParameters.setJpegQuality(100);
mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
} else {
mRecordVideoManager.setPreviewSize(previewSize);
}
mCameraParameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation));
setAutoFocusInternal(mAutoFocus);
setFlashInternal(mFlash);
mCamera.setParameters(mCameraParameters);
if (mShowingPreview) {
startPreview();
}
}
检查相机是否支持该宽高比
/**
* 检查相机是否支持该宽高比
*
* @param mAspectRatio
* @return
*/
private AspectRatio checkAspectRatio(AspectRatio mAspectRatio) {
AspectRatio r = null;
for (AspectRatio ratio : mPreviewSizes.ratios()) {
r = ratio;
if (ratio.equals(mAspectRatio)) {
return ratio;
}
}
return r;
}
获取最佳的预览尺寸
//用来比对的绝对值
private int mPreviewAbs = -1;
/**
* 设置最佳显示尺寸
*
* @param sizes
* @return
*/
@SuppressWarnings("SuspiciousNameCombination")
private Size chooseOptimalSize(SortedSet<Size> sizes) {
if (!mPreview.isReady()) { // Not yet laid out
return sizes.last(); // Return the smallest size
}
int surfaceWidth = mPreview.getWidth();
int surfaceHeight = mPreview.getHeight();
Size result = sizes.last();
for (Size size : sizes) {
//根据像素点(面积)计算最符合目标的分辨率
int referencePixels = surfaceWidth * surfaceHeight;
int picturePixels = size.getWidth() * size.getHeight();
int abs = Math.abs(referencePixels - picturePixels);
if (mPreviewAbs < 0 || mPreviewAbs > abs) {
mPreviewAbs = abs;
result = size;
} else {
mPreviewAbs = -1;
break;
}
}
return result;
}
网友评论