【Android Camera1】Camera1 Parameters参数详解(一)—— Size (preview/picture/thumbnail)

1、简介

本篇文章将对Camera1和Size相关的参数,逐个进行详细解析。在Camera1源码分析文章里、已阐述过相关源码。并提供了读取和更新Parameters的2个方法如下:
读取Parameters

  public static @Nullable Camera.Parameters getCameraParameters(@NonNull Camera camera) {
        try {
            return camera.getParameters();
        }catch (Exception e){
            return null;
        }
    }	

更新Parameters

    public static boolean setCameraParameters(@NonNull Camera camera, @NonNull Camera.Parameters parameters) {
        try {
            camera.setParameters(parameters);
            return true;
        }catch (Exception e){
            return false;
        }
    }

本篇文章涉及的具体参数如下:

Key变量名Key变量值
KEY_PREVIEW_SIZEpreview-size
KEY_PREVIEW_FORMATpreview-format
KEY_PREVIEW_FRAME_RATEpreview-frame-rate
KEY_PREVIEW_FPS_RANGEpreview-fps-range
KEY_PICTURE_SIZEpicture-size
KEY_PICTURE_FORMATpicture-format
KEY_JPEG_THUMBNAIL_SIZEjpeg-thumbnail-size
KEY_JPEG_THUMBNAIL_WIDTHjpeg-thumbnail-width
KEY_JPEG_THUMBNAIL_HEIGHTjpeg-thumbnail-height
KEY_JPEG_THUMBNAIL_QUALITYjpeg-thumbnail-quality
KEY_JPEG_QUALITYjpeg-quality

2.preview-size

说明:1. 当前相机预览的preview-size:如1280 * 960
2. 通过设置该key不同的value值可以控制camera预览图的分辨率。
3. 相机的输出流和手机竖直成90度夹角,所以width > height
相关KEYKEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX
preview-size-values
KEY_PICTURE_SIZE
picture-size
KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX
picture-size-values
方法public Size getPreviewSize()
public List getSupportedPreviewSizes()
public void setPreviewSize(int width, int height)
注意1. 可以不设置
2. 如果设置一定要设置 getSupportedPreviewSizes()返回的Size,不然会抛错

3.preview-format

说明:1.当前相机预览的图片格式如YV12 YUY2 NV16 YUV422SP YUV420SP
相关KEYpicture-format
方法public int getPreviewFormat()
public void setPreviewFormat(int pixel_format)
public List getSupportedPreviewFormats()
注意1. 可以不设置 有默认值
2. 如果设置一定要设置 getSupportedPreviewFormats()返回的结果,不然会抛错

3.1 官方注释

Sets the image format for preview pictures.
If this is never called, the default format will be ImageFormat.NV21, which uses the NV21 encoding format.
Use getSupportedPreviewFormats to get a list of the available preview formats.
It is strongly recommended that either ImageFormat.NV21 or ImageFormat.YV12 is used, since they are supported by all camera devices.
For YV12, the image buffer that is received is not necessarily tightly packed, as there may be padding at the end of each row of pixel data, as described in ImageFormat.YV12. For camera callback data, it can be assumed that the stride of the Y and UV data is the smallest possible that meets the alignment requirements. That is, if the preview size is width x height, then the following equations describe the buffer index for the beginning of row y for the Y plane and row c for the U and V planes:
 
 yStride   = (int) ceil(width / 16.0) * 16;
 uvStride  = (int) ceil( (yStride / 2) / 16.0) * 16;
 ySize     = yStride * height;
 uvSize    = uvStride * height / 2;
 yRowIndex = yStride * y;
 uRowIndex = ySize + uvSize + uvStride * c;
 vRowIndex = ySize + uvStride * c;
 size      = ySize + uvSize * 2;
 
          
Params:
pixel_format – the desired preview picture format, defined by one of the ImageFormat constants. (E.g., ImageFormat.NV21 (default), or ImageFormat.YV12)
See Also:
ImageFormat, getSupportedPreviewFormats

默认为ImageFormat.NV21

3.2 CameraFormat VS PixelFormat

        // Formats for setPreviewFormat and setPictureFormat.
        private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
        private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
        private static final String PIXEL_FORMAT_YUV422I = "yuv422i-yuyv";
        private static final String PIXEL_FORMAT_YUV420P = "yuv420p";
        private static final String PIXEL_FORMAT_RGB565 = "rgb565";
        private static final String PIXEL_FORMAT_JPEG = "jpeg";
        private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";

        private String cameraFormatForPixelFormat(int pixel_format) {
            switch(pixel_format) {
            case ImageFormat.NV16:      return PIXEL_FORMAT_YUV422SP;
            case ImageFormat.NV21:      return PIXEL_FORMAT_YUV420SP;
            case ImageFormat.YUY2:      return PIXEL_FORMAT_YUV422I;
            case ImageFormat.YV12:      return PIXEL_FORMAT_YUV420P;
            case ImageFormat.RGB_565:   return PIXEL_FORMAT_RGB565;
            case ImageFormat.JPEG:      return PIXEL_FORMAT_JPEG;
            default:                    return null;
            }
        }

        private int pixelFormatForCameraFormat(String format) {
            if (format == null)
                return ImageFormat.UNKNOWN;

            if (format.equals(PIXEL_FORMAT_YUV422SP))
                return ImageFormat.NV16;

            if (format.equals(PIXEL_FORMAT_YUV420SP))
                return ImageFormat.NV21;

            if (format.equals(PIXEL_FORMAT_YUV422I))
                return ImageFormat.YUY2;

            if (format.equals(PIXEL_FORMAT_YUV420P))
                return ImageFormat.YV12;

            if (format.equals(PIXEL_FORMAT_RGB565))
                return ImageFormat.RGB_565;

            if (format.equals(PIXEL_FORMAT_JPEG))
                return ImageFormat.JPEG;

            return ImageFormat.UNKNOWN;
        }

这里面出现了很多的格式:
YV12 YUY2 NV16 YUV422SP YUV420SP 等等;详细解释请参看:Camera理论知识和基本原理【7】图像表示方式和存储格式

4. preview-frame-rate

已废弃,参考【5. preview-fps-range】

5. preview-fps-range

说明:preview - fps
相关KEYpreview-fps-range
preview-fps-range-values
方法public List<int[]> getSupportedPreviewFpsRange()
public void getPreviewFpsRange(int[] range)
public void setPreviewFpsRange(int min, int max)

5.1 说明

preview-fps-range通过如下函数设置camera1预览的fps范围:


 /**
  * Sets the minimum and maximum preview fps. This controls the rate of
  * preview frames received in {@link PreviewCallback}. The minimum and
  * maximum preview fps must be one of the elements from {@link
  * #getSupportedPreviewFpsRange}.
  *
  * @param min the minimum preview fps (scaled by 1000).
  * @param max the maximum preview fps (scaled by 1000).
  * @throws RuntimeException if fps range is invalid.
  * @see #setPreviewCallbackWithBuffer(Camera.PreviewCallback)
  * @see #getSupportedPreviewFpsRange()
  */
 public void setPreviewFpsRange(int min, int max) {
     set(KEY_PREVIEW_FPS_RANGE, "" + min + "," + max);
 }

分析:

  1. 最大,最小,是个范围
  2. scale 1000倍数
  3. 必须是getSupportedPreviewFpsRange 返回的值
  4. 影响Camera.PreviewCallback-> onPreviewFrame的调用频率

5.2 举例

通过如下可获取当前preview-range

int[] previewRange = new int[2];
mCameraParameters.getPreviewFpsRange(previewRange);

相机默认会返回[5000, 30000],注意minValue和maxValue不是一致的。这里给出一个范围,实际相机会自动根据摄像头设备捕捉不同场景去自动调节对应的FPS。如果一直不移动,Camera会降低onPreviewFrame回掉的频率,即fps会降低。

我们可通过如下函数获取当前设备支持的preview-range-values。然后设置不同的值:

public List<int[]> getSupportedPreviewFpsRange() {
    String str = get(KEY_PREVIEW_FPS_RANGE + SUPPORTED_VALUES_SUFFIX);
    return splitRange(str);
}

public void setPreviewFpsRange(int min, int max)的参数一定要是相机支持的参数

实际运行调用getSupportedPreviewFpsRange输出具体的值为:

SupportedPreviewFrameRates = [10000, 10000]
SupportedPreviewFrameRates = [15000, 15000]
SupportedPreviewFrameRates = [20000, 20000]
SupportedPreviewFrameRates = [5000, 30000]
SupportedPreviewFrameRates = [30000, 30000]
curPreviewFrameRates = [5000, 30000]

6. picture-size

类比preview-size

说明:1. 当前相机预览的picture-size:如1440 * 1280
2. 通过设置该key不同的value值可以控制camera capture 拍照结果图的分辨率。
3. 相机的输出流和手机竖直成90度夹角,所以width > height
相关KEYKEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX
picture-size-values
KEY_PREVIEW_SIZE
preview-size
KEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX
preview-size-values
方法public Size getPictureSize()
public List getSupportedPictureSizes()
public void setPictureSize(int width, int height)
注意1. 可以不设置
2. 如果设置一定要设置 getSupportedPictureSizes()返回的Size,不然会抛错

基本和preview-size类似,可互相参考共同了解。

7. picture-format

基本和preview-format类似,参看【3】

8. jpeg-thumbnail

说明:1. 当前相机capture thumb 缩略图到相关参数设置。
2. 通过设置相关key不同的value值可以控制camera capture 缩略图的宽高,图片质量。
3. 相机的输出流和手机竖直成90度夹角,所以width > height
相关KEYKEY_JPEG_THUMBNAIL_SIZE
jpeg-thumbnail-size
KEY_JPEG_THUMBNAIL_WIDTH
jpeg-thumbnail-width
KEY_JPEG_THUMBNAIL_HEIGHT
jpeg-thumbnail-height
KEY_JPEG_THUMBNAIL_QUALITY
jpeg-thumbnail-quality
方法public Size getJpegThumbnailSize()
public void setJpegThumbnailSize(int width, int height)
public Size getJpegThumbnailSize()
public List getSupportedJpegThumbnailSizes()
public void setJpegThumbnailQuality(int quality)
public int getJpegThumbnailQuality()

9. jpeg-quality

说明:1. 当前相机capture picture 图片质量。
2. value 范围 1 - 100
方法public void setJpegQuality(int quality)
public int getJpegQuality()
影响因素quality越高,图片文件大小越大
quality越高,拍照性能越差
quality越高,图片质量越清楚

说明:
jpeg-quality和最终生成的jpeg图片质量有关系。 值越小,则对原始图压缩的越厉害。在不同的场景下可综合多方面因素设置不同的jpeg-quality。如:

  • 低端机,可适当调低jpeg-quality的值
  • 分辨率较低的图片也可适当调低jpeg-quality的值

10. END

后续将阐述:
【Android Camera1】Camera1 Parameters参数详解(二)—— 3A算法 (AF/AE/AWB)
【Android Camera1】Camera1 Parameters参数详解(三)—— zoom,other

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我明白了。以下是用 Android Studio 编写代码将 CameraX 前置相机添加到 Activity 右上角的步骤: 首先,你需要在你的Activity的布局XML文件中添加一个 FrameLayout 来展示相机预览。代码如下: ``` <FrameLayout android:id="@+id/camera_preview_container" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 然后,在你的 Activity 的 onCreate() 方法中获取 CameraProvider 实例、绑定相机生命周期、以及创建 Preview 和 ImageCapture 实例。 ``` // 定义预览用例 val preview = Preview.Builder().build() preview.setSurfaceProvider(camera_preview_container.createSurfaceProvider()) // 定义拍照用例 val imageCapture = ImageCapture.Builder().build() // 定义相机生命周期,以便 当 Activity 生命周期变化时相机能够跟随变化 val cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA val cameraProviderFuture = ProcessCameraProvider.getInstance(this) cameraProviderFuture.addListener(Runnable { val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get() cameraProvider.unbindAll() cameraProvider.bindToLifecycle( this, cameraSelector, preview, imageCapture ) }, ContextCompat.getMainExecutor(this)) ``` 然后,在布局文件中添加一个 ImageView 来承载缩略图,并在 onCreate() 方法中设置点击事件。 ``` val thumbnailImageView = ImageView(this) thumbnailImageView.setOnClickListener { imageCapture.takePicture( ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageCapturedCallback() { override fun onCaptureSuccess(image: ImageProxy) { // do something with image data } override fun onError(exception: ImageCaptureException) { // handle error } } ) } ``` 最后,在 Activity 的 onCreateOptionsMenu() 方法中,添加一个 MenuItem 来触发显示缩略图的 ImageView。 ``` override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.camera_menu, menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.show_thumbnail -> { if (thumbnailImageView.parent != null) { (thumbnailImageView.parent as ViewGroup).removeView(thumbnailImageView) } camera_preview_container.addView(thumbnailImageView) true } else -> return super.onOptionsItemSelected(item) } } ``` 这样就可以在 Activity 右上角添加一个菜单项,点击后展示缩略图了。希望这个答案能够帮助到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值