Android Camera2.0 结合ImageReader拍照并解决图片偏转问题

news/2024/11/19 23:30:12/

前文Android Camera2.0 API实现摄像头预览并获取人脸关键坐标已经介绍了Camera2.0的基础内容,在2.0的API中,要想实现拍照功能,则要借助于ImageReader。

首先在自定义的TextureView.SurfaceTextureListener的实现类中,维护ImageReader的引用

private ImageReader mImageReader ;

然后在setUpCamera方法中对ImageReader进行初始化

/*** 设置camera2.0的初始化参数*/private void setUpCamera() {cameraManager = (CameraManager)mContext.getSystemService(Context.CAMERA_SERVICE);try{for (String id : cameraManager.getCameraIdList()) {//获取代表摄像头特征类characteristicscharacteristics = cameraManager.getCameraCharacteristics(id);//如果是前置摄像头if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {mCameraId = id ;StreamConfigurationMap streamConfigurationMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);sizes = streamConfigurationMap.getOutputSizes(SurfaceHolder.class);//设置预览大小mPreviewSize = sizes[0];//imageReader初始化mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(),mPreviewSize.getHeight(),ImageFormat.JPEG,2 );mImageReader.setOnImageAvailableListener(onImageAvailableListener , mBackgroundHandler);//获取人脸检测参数int[] FD =characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);int maxFD=characteristics.get(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);if (FD.length>0) {List<Integer> fdList = new ArrayList<>();for (int FaceD : FD) {fdList.add(FaceD);Log.e(TAG, "setUpCameraOutputs: FD type:" + Integer.toString(FaceD));}Log.e(TAG, "setUpCameraOutputs: FD count" + Integer.toString(maxFD));if (maxFD > 0) {mFaceDetectSupported = true;mFaceDetectMode = Collections.max(fdList);}}}}} catch ( CameraAccessException e ){e.printStackTrace();}}

然后将ImageReader的Surface添加进CaptureRequest.Builder中
在startPreview()方法中添加

previewRequestBuilder.addTarget(mImageReader.getSurface());

接下来创建一个类实现ImageReader.OnImageAvailableListener接口,在其中获取每一帧的Image对象,并生成一个Bitmap,并对该Bitmap进行镜像和旋转操作,因为摄像头获取的原始图像和预览中见到的图像是并不一样

/**
*OnImageAvailableListener实现类
*/private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {@Overridepublic void onImageAvailable(ImageReader reader) {Image image = reader.acquireNextImage() ;ByteBuffer byteBuffer = image.getPlanes()[0].getBuffer();byte[] bytes = new byte[byteBuffer.remaining()];byteBuffer.get(bytes);try {Bitmap temp = BitmapFactory.decodeByteArray(bytes,0,bytes.length);Bitmap newBitmap = Bitmap.createBitmap(mPreviewSize.getWidth(),mPreviewSize.getWidth(),temp.getConfig());Canvas canvas = new Canvas(newBitmap);Paint paint = new Paint();Matrix matrix = new Matrix();//图片镜像并旋转90度matrix.setScale(-1, 1);matrix.postTranslate(temp.getWidth(), 0);matrix.postRotate(90 ,temp.getWidth()/2,temp.getHeight()/2);matrix.postTranslate(0,(temp.getWidth()-temp.getHeight())/2);canvas.drawBitmap(temp, matrix , paint );File newFile = new File( Environment.getExternalStorageDirectory() , "345.jpg");BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));newBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);bos.flush();bos.close();temp.recycle();newBitmap.recycle();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {image.close();byteBuffer.clear();}image.close();}};

上面做的是用ImageReader获取每一帧实时图像,要想实现拍照,调用CameraCaptureSession的capture方法即可

public void captureStillImage(){try {CaptureRequest.Builder captureStillBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);captureStillBuilder.addTarget(mImageReader.getSurface());// 设置自动对焦模式captureStillBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);// 设置自动曝光模式captureStillBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);int rotation = ((Activity)mContext).getWindowManager().getDefaultDisplay().getRotation();captureStillBuilder.set( CaptureRequest.JPEG_ORIENTATION ,ORIENTATIONS.get(rotation));CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {@Overridepublic void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {super.onCaptureCompleted(session, request, result);Toast.makeText(mContext,"Image Captured" , Toast.LENGTH_SHORT).show();}};captureSession.stopRepeating();captureSession.capture( captureStillBuilder.build() , captureCallback , null );captureSession.setRepeatingRequest(captureRequest, new CameraCaptureSession.CaptureCallback() {@Overridepublic void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) {super.onCaptureStarted(session, request, timestamp, frameNumber);}},mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}

在成员变量中设置ROTATION

//设置Surface旋转角private static final SparseIntArray ORIENTATIONS = new SparseIntArray();static {ORIENTATIONS.append(Surface.ROTATION_0,90);ORIENTATIONS.append(Surface.ROTATION_90,0);ORIENTATIONS.append(Surface.ROTATION_180,270);ORIENTATIONS.append(Surface.ROTATION_270,180);}

也欢迎关注个人公众号,移动开发,音视频,图形图像,大厂内推,不定时更新
在这里插入图片描述


http://www.ppmy.cn/news/789038.html

相关文章

Baumer工业相机堡盟相机使用CameraExplorer软件进行相机参数保存与 UserSet参数设置

项目场景&#xff1a; Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能&#xff0c;可以实时传输高分辨率图像。此外&#xff0…

记录一下Jetson突然无法识别csi219相机笔记

sudo /opt/nvidia/jetson-io/jetson-io.py 这几天搞jetbot&#xff0c;突然发现我的小车无法使用219相机了&#xff0c;也没用几次的呀&#xff0c;更换了Image,不行更换了boot目录还不行&#xff0c;dmesg看不到219的信息&#xff0c;完犊子了坏了&#xff0c;刷了一个新系统…

解决Google人机验证reCaptcha失效问题

安装Redirector插件 Firefox浏览器1. 下载Firefox浏览器&#xff0c;并安装插件2. 打开Redirector插件的界面3. 弹出如下界面4. 按照如下形式填写 Chrome浏览器 Firefox浏览器 1. 下载Firefox浏览器&#xff0c;并安装插件 2. 打开Redirector插件的界面 3. 弹出如下界面 4. 按…

Orin 调试GMSL camera 96712手册重点

1.MAX96712 有4 GMSL Links/PHYs(A,B,C and D) 可以配置成的模式: 整体框图: 详细框图: 内部pipeline 其中PORTA和PORTB 对应4lane输出 PORTC/PORTD 对应2lane输出 PORTE/PORTF对应2lane输出 需要配置相应的寄存器 两种聚合方式: Side-by-Side and Line-Interleaved …

对电脑连接工业相机的一些想法,以及CameraFinder.Enumerate()找不到相机的原因

在pylonView中使用静态IP配置完basler的IP地址&#xff0c;能够打开相机&#xff0c;并且拍照。如下图所示&#xff1a; 但是&#xff0c;在运行basler相机的C#程序时&#xff0c;报如下错误&#xff1a; 在寻找相机的个数时&#xff0c;总是找不到相机&#xff0c;一直显示 …

CCD工业相机电脑连接正常但无法采集图像的相关设置

CCD工业相机电脑连接正常但无法采集图像的相关设置 解决方法 第一步&#xff1a; 首先进入到控制板面。 对于Win10系统&#xff0c;我们可输入“WINR”&#xff0c;并输入control&#xff0c;进入控制板面。 第二步&#xff1a; 找到查看网络状态和任务&#xff0c;点击相…

aardio 谷歌浏览器自动化 (四) 浏览器动作和信息获取

浏览器动作 示例1: import chrome.driverex import process.imageViewdriver chrome.driverex()//禁止显示浏览器被控制提示 driver.disableAutomation()wb driver.startBrowser()wb.go("https://tieba.baidu.com/") wb.wait() wb.go("https://www.sohu.com/…

Android检查相机或日历等授权情况

检查权限是否授权 //检查日历 Manifest.permission.WRITE_CALENDAR //日历读写是否授权 //依赖 import androidx.core.app.ActivityCompat; //getActivity()为 Activity.thisBoolean flag false; //如果是MainActivity 将getActivity()改为MainActivity.this if ((ActivityC…