news 2026/6/12 16:50:48

RK3576-Android15原生相机Camera2 修改USB相机预览和成像方向

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RK3576-Android15原生相机Camera2 修改USB相机预览和成像方向

提示:RK3576-Android15 谷歌原生相机Camera2 使用客户定制的USB相机,发现预览和成像方向错位,相机软件需要适配USB相机

文章目录

  • 前言-需求
  • 一、基础-参考资料-思路
    • 参考资料
    • 基础补充
      • 架构图了解
      • Camera相关专栏
      • 零散知识了解
      • 部分相机源码参考,学习API使用,梳理流程,偏应用层
    • 实现需求思路
  • 二、修改文件
  • 三、实现方案
    • 修改预览方向-TextureViewHelper
    • 修改成像方向-CameraUtil
  • 四、源码解读-思路
    • 困难点-日志工具
    • 预览方向调试
    • 拍照成像调试
  • 总结

前言-需求

产品是大屏平板类型设备4K 32寸 随心屏,客户自己打样了USB相机,产品出厂用的就是USB相机设备

问题:

  • USB相机安装上去发现 拍照预览有一个方向是倒置的
  • 拍照的照片 成像都是倒置的,旋转了180度
  • 视频预览都是倒置的,视频成像到是没什么问题。

所以要解决的问题有3个:拍照一个方向和视频横竖屏方向预览倒置了,拍照成像方向旋转了180度。

一、基础-参考资料-思路

参考资料

Camera2 实现重力感应四个方向调试相机预览

基础补充

相机整个模块确实太专业、复杂了。 无论从硬件外设、驱动【USBCamera免驱】、相机 都比较专业、覆盖面及广,针对思考中的问题 给出自己认为比较好相关博客,方便了解,助于梳理流程、提升认知。

对于上层应用或者Framework 系统应用开发者,只需要了解基本的架构、API、使用方法,当然这些也不简单的
下面提供部分资源,方便快速了解,充电:

架构图了解

MTKCamera2相机架构
Camera2架构
Android Camera架构简析

Camera相关专栏

Camera Framework 专栏
小驰私房菜系列
小驰私房菜MTK系列
小驰Camera 开发系列
Camera 相机开发
展讯平台 Camera
官方文档:谷歌官方 API 描述

零散知识了解

MTK 相机UI介绍
Camera2 相机认知
Camera2学习笔记
camera2关于拍照预览方向旋转90度和拍照图片镜像功能实现
Camera2 预览集成、简单拍照:熟悉预览步骤流程比较有用
Camera镜像上下左右颠倒问题的解决办法
MTK相机成像质量差
Camera应用分析

部分相机源码参考,学习API使用,梳理流程,偏应用层

极客相机 Camera2 API
Camera2 API详解
极客相机源码
Camera2 相机Demo
Camera2 专业相机Demo
拍照、预览、录像Demo
使用Camera2 拍照

实现需求思路

其实对于相机Camera2 的修改,难点在于:Camera2 源码量或者说Android体系下AOSP中各个模块的代码量本身太大,每个模块都有自己的架构,不同Android版本架构思路其实不一样的 并不能直接复用。 所以针对性看大量的源码存在一定困难、理解起来更困难、调试起来更是天方夜谭,只能编译调试。

但是,如果就预览方向和相机拍照成像方向,根据经验思路如下:基于这个思路极大方便针对性查看源码

调整场景核心方法/API关键考虑因素主要实现思路
预览方向TextureView.setTransform(matrix)设备物理方向、传感器方向、预览显示计算变换矩阵并应用到显示控件
拍照方向CaptureRequest.JPEG_ORIENTATION设备物理方向、传感器方向、照片存储设置JPEG图像写入时的旋转元数据

二、修改文件

packages/apps/Camera2/src/com/android/camera/TextureViewHelper.java packages/apps/Camera2/src/com/android/camera/util/CameraUtil.java

这里面一个文件是修改预览方向,TextureViewHelper见名知意;一个是设置成像方向旋转。

三、实现方案

修改预览方向-TextureViewHelper

第一步:导包

// modify by fangchen startimportandroid.content.res.Configuration;importcom.android.camera.app.CameraServices;importcom.android.camera.app.CameraServicesImpl;importcom.android.camera.settings.SettingsManager;importcom.android.camera.settings.Keys;// modify by fangchen end

第二步:拍照预览情况下判断横竖屏方向针对某一个方向进行预览旋转,实际情况就一个方向预览倒置。 方法updateTransform(Matrix matrix)修改如下:

publicvoidupdateTransform(Matrixmatrix){android.util.Log.d(TAGT,"=====updateTransform===111==");RectFpreviewRect=newRectF(0,0,mWidth,mHeight);matrix.mapRect(previewRect);floatpreviewWidth=previewRect.width();floatpreviewHeight=previewRect.height();if(previewHeight==0||previewWidth==0){Log.e(TAG,"Invalid preview size: "+previewWidth+" x "+previewHeight);return;}floataspectRatio=previewWidth/previewHeight;aspectRatio=aspectRatio<1?1/aspectRatio:aspectRatio;if(aspectRatio!=mAspectRatio){setAspectRatio(aspectRatio);}RectFpreviewAreaBasedOnAspectRatio=mCaptureLayoutHelper.getPreviewRect();MatrixaddtionalTransform=newMatrix();addtionalTransform.setRectToRect(previewRect,previewAreaBasedOnAspectRatio,Matrix.ScaleToFit.CENTER);matrix.postConcat(addtionalTransform);// modify by fangchen startif(isPortraitByConfiguration()){android.util.Log.d(TAGT,"=====isPortraitByConfiguration=== ==");matrix.postRotate(180,previewWidth/2f,previewHeight/2f);}// modify by fangchen endmPreview.setTransform(matrix);updatePreviewArea(matrix);}// modify by fangchen startpublicbooleanisPortraitByConfiguration(){intorientation=mAppController.getAndroidContext().getResources().getConfiguration().orientation;returnorientation==Configuration.ORIENTATION_PORTRAIT;}// modify by fangchen end

第三步:视频预览情况下进行预览旋转,实际情况是视频模式下预览都倒置,那么就直接旋转180度。 方法updateTransform()修改如下:

privatebooleanupdateTransform(){Log.v(TAG,"updateTransform");android.util.Log.d(TAGT,"=====updateTransform==0000= ==");if(!mAutoAdjustTransform){returnfalse;}if(mAspectRatio==MATCH_SCREEN||mAspectRatio<0||mWidth==0||mHeight==0){returntrue;}Matrixmatrix=newMatrix();CameraIdcameraKey=mCameraProvider.getCurrentCameraId();intcameraId=-1;try{cameraId=cameraKey.getLegacyValue();}catch(UnsupportedOperationExceptionignored){Log.e(TAG,"TransformViewHelper does not support Camera API2");}// Only apply this fix when Current Active Module is Photo module AND// Phone is Nexus4 The enhancement fix b/20694189 to original fix to// b/19271661 ensures that the fix should only be applied when:// 1) the phone is a Nexus4 which requires the specific workaround// 2) CaptureModule is enabled.// 3) the Camera Photo Mode Or Capture Intent Photo Mode is activeif(ApiHelper.IS_NEXUS_4&&mAppController.getCameraFeatureConfig().isUsingCaptureModule()&&(mAppController.getCurrentModuleIndex()==mCameraModeId||mAppController.getCurrentModuleIndex()==mCaptureIntentModeId)){Log.v(TAG,"Applying Photo Mode, Capture Module, Nexus-4 specific fix for b/19271661");mOrientation=CameraUtil.getDisplayRotation((Activity)mPreview.getContext());matrix=getPreviewRotationalTransform(mOrientation,newRectF(0,0,mWidth,mHeight),mCaptureLayoutHelper.getPreviewRect());}elseif(cameraId>=0){// Otherwise, do the default, legacy action.CameraDeviceInfo.Characteristicsinfo=mCameraProvider.getCharacteristics(cameraId);matrix=info.getPreviewTransform(mOrientation,newRectF(0,0,mWidth,mHeight),mCaptureLayoutHelper.getPreviewRect());}else{// Do Nothing}// modify by fangchen startmatrix.postRotate(180,mWidth/2f,mHeight/2f);// modify by fangchen startmPreview.setTransform(matrix);updatePreviewArea(matrix);returntrue;}

修改成像方向-CameraUtil

如上修改思路,对于拍照成像方向,找一下:CaptureRequest.JPEG_ORIENTATION相关代码,就是Camera2 机制里面,拍照时候去设置一个参数。 当然还有一种方案就是存储的时候 进行旋转【这里不处理,尽量不要在上层处理 , 直接处理成像流】
getImageRotation方法中添加方向多180度即可,如下:

/** * Given the camera sensor orientation and device orientation, this returns a clockwise angle * which the final image needs to be rotated to be upright on the device screen. * * @param sensorOrientation Clockwise angle through which the output image needs to be rotated * to be upright on the device screen in its native orientation. * @param deviceOrientation Clockwise angle of the device orientation from its * native orientation when front camera faces user. * @param isFrontCamera True if the camera is front-facing. * @return The angle to rotate image clockwise in degrees. It should be 0, 90, 180, or 270. */publicstaticintgetImageRotation(intsensorOrientation,intdeviceOrientation,booleanisFrontCamera){// The sensor of front camera faces in the opposite direction from back camera.if(isFrontCamera){deviceOrientation=(360-deviceOrientation)%360;}android.util.Log.d(TAGT,"=====getImageRotation====before:=="+(sensorOrientation+deviceOrientation)%360);android.util.Log.d(TAGT,"=====getImageRotation====after:=="+(sensorOrientation+deviceOrientation+180)%360);// return (sensorOrientation + deviceOrientation) % 360;return(sensorOrientation+deviceOrientation+180)%360;}

四、源码解读-思路

困难点-日志工具

一方面代码量大、不同Android版本Camera2 架构还是有少许变化的;另外一方面 日志,AOSP 里面每个模块都有日志工具。目的是有日志打印,所以日志工具、模式 要搞清楚,但是很多时候发现日志就是不打印 所以最好的方案就是把日志打印打出来,搞清楚 日志架构;实在不行 那么就自己用自己日志吧,方便调试。

如下日志打印:android.util.Log.d(TAGT,"=====getImageRotation====before:=="+(sensorOrientation + deviceOrientation) % 360);

预览方向调试

预览方向以前的经验:TextureView.setTransform(matrix)
在源码里面就直接搜索到了,如下:所以大概率就是要修改TextureViewHelper

看类注释和这个类实现的类TextureView.SurfaceTextureListener 就大概率猜到这个类就是需要修改的类了,剩下的就是看日志 、分析流程的事情了。

拍照成像调试

根据经验和基础:CaptureRequest.JPEG_ORIENTATION,直接搜索相关代码

代码如下:

所以都指向了一个类的一个方法CameraUtil.getJpegRotation ->getImageRotation修改即可

/** * Given the device orientation and Camera2 characteristics, this returns * the required JPEG rotation for this camera. * * @param deviceOrientationDegrees the clockwise angle of the device orientation from its * natural orientation in degrees. * @return The angle to rotate image clockwise in degrees. It should be 0, 90, 180, or 270. */publicstaticintgetJpegRotation(intdeviceOrientationDegrees,CameraCharacteristicscharacteristics){if(deviceOrientationDegrees==OrientationEventListener.ORIENTATION_UNKNOWN){return0;}booleanisFrontCamera=characteristics.get(CameraCharacteristics.LENS_FACING)!=CameraMetadata.LENS_FACING_BACK;intsensorOrientation=characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);returngetImageRotation(sensorOrientation,deviceOrientationDegrees,isFrontCamera);}/** * Given the camera sensor orientation and device orientation, this returns a clockwise angle * which the final image needs to be rotated to be upright on the device screen. * * @param sensorOrientation Clockwise angle through which the output image needs to be rotated * to be upright on the device screen in its native orientation. * @param deviceOrientation Clockwise angle of the device orientation from its * native orientation when front camera faces user. * @param isFrontCamera True if the camera is front-facing. * @return The angle to rotate image clockwise in degrees. It should be 0, 90, 180, or 270. */publicstaticintgetImageRotation(intsensorOrientation,intdeviceOrientation,booleanisFrontCamera){// The sensor of front camera faces in the opposite direction from back camera.if(isFrontCamera){deviceOrientation=(360-deviceOrientation)%360;}return(sensorOrientation+deviceOrientation)%360;}

总结

  • 对于有时间和精力的朋友,强烈建议多看看基础知识储备基本技能知识点
  • 对于Camera2 修改,建议多总结,代码量大且架构变化多,不同平台和不同Android版本,导致代码变化大,建议多针对性看并且讲究方法
  • 日志很重要,看日志针对性看流程
  • 根据经验,针对性得看需求知识点。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/30 11:07:06

多语言翻译服务质量保障:通信无国界的基石

多语言翻译服务质量保障&#xff1a;通信无国界的基石 在全球化浪潮席卷各行各业的今天&#xff0c;企业跨国协作、科研机构联合攻关、用户跨语言社交已成常态。然而&#xff0c;语言鸿沟依然是信息流通的隐形壁垒。尽管深度学习驱动的神经机器翻译&#xff08;NMT&#xff09;…

作者头像 李华
网站建设 2026/6/9 23:54:41

跨区域数据同步加速:全球化业务的底层支撑

跨区域数据同步加速&#xff1a;全球化业务的底层支撑 在当今全球化的数字生态中&#xff0c;用户对服务响应速度的容忍度正变得越来越低。无论是欧洲消费者在午夜下单购物、东南亚用户与语音助手对话&#xff0c;还是美洲金融机构进行实时反欺诈决策&#xff0c;他们都不希望因…

作者头像 李华
网站建设 2026/6/4 5:55:34

植物养护提醒机器人:阳台绿植不再轻易枯萎

植物养护提醒机器人&#xff1a;阳台绿植不再轻易枯萎 在城市生活的方寸阳台上&#xff0c;一盆绿植往往承载着人们对自然的向往。然而&#xff0c;工作繁忙、出差频繁&#xff0c;常常让人忘记浇水、忽视光照——再顽强的生命也扛不住长期疏于照料。于是&#xff0c;我们开始思…

作者头像 李华
网站建设 2026/6/5 10:57:05

商标近似度判断AI:品牌维权的新手段

商标近似度判断AI&#xff1a;品牌维权的新手段 在电商平台每秒新增成千上万商品的今天&#xff0c;一个伪造的“耐克勾”图标可能正悄然出现在某个冷门店铺中。传统靠人工审核来识别这些细微差别的做法早已不堪重负——不仅响应慢&#xff0c;还极易遗漏。而当侵权行为变得越来…

作者头像 李华
网站建设 2026/6/4 15:17:25

基于51单片机的步进电机调速系统设计

基于51单片机的步进电机调速系统 &#xff08;仿真&#xff0b;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.按键可以控制电机正、反转&#xff0c;加、减速&#xff0c;停止&#xff1b; 2.一位7段数码管实时显示档位&#xf…

作者头像 李华