android Camera2

举报
风吹稻花香 发表于 2021/06/05 01:13:33 2021/06/05
【摘要】   控件: import android.view.TextureView; 这个是代码: https://github.com/plumcot/Camera2Demo/blob/master/src/com/example/camera2demo/Camera2Demo.java   获取图片数据不对,应该是:   privat...

 

控件:

import android.view.TextureView;

这个是代码:

https://github.com/plumcot/Camera2Demo/blob/master/src/com/example/camera2demo/Camera2Demo.java

 

获取图片数据不对,应该是:

 


  
  1. private void setupImageReader() {
  2. //前三个参数分别是需要的尺寸和格式,最后一个参数代表每次最多获取几帧数据,本例的2代表ImageReader中最多可以获取两帧图像流
  3. mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(),
  4. ImageFormat.JPEG, 2);
  5. //监听ImageReader的事件,当有图像流数据可用时会回调onImageAvailable方法,它的参数就是预览帧数据,可以对这帧数据进行处理
  6. mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
  7. @Override
  8. public void onImageAvailable(ImageReader reader) {
  9. Image image = reader.acquireLatestImage();
  10. //我们可以将这帧数据转成字节数组,类似于Camera1的PreviewCallback回调的预览帧数据
  11. ByteBuffer buffer = image.getPlanes()[0].getBuffer();
  12. byte[] data = new byte[buffer.remaining()];
  13. buffer.get(data);
  14. image.close();
  15. }
  16. }, null);
  17. }

 


  
  1. package com.mtcnn_as;
  2. import java.nio.ByteBuffer;
  3. import java.util.Arrays;
  4. import android.Manifest;
  5. import android.app.Activity;
  6. import android.content.Context;
  7. import android.content.pm.PackageManager;
  8. import android.graphics.Bitmap;
  9. import android.graphics.BitmapFactory;
  10. import android.graphics.ImageFormat;
  11. import android.graphics.Matrix;
  12. import android.graphics.SurfaceTexture;
  13. import android.hardware.camera2.CameraAccessException;
  14. import android.hardware.camera2.CameraCaptureSession;
  15. import android.hardware.camera2.CameraCharacteristics;
  16. import android.hardware.camera2.CameraDevice;
  17. import android.hardware.camera2.CameraManager;
  18. import android.hardware.camera2.CaptureRequest;
  19. import android.hardware.camera2.params.StreamConfigurationMap;
  20. import android.media.Image;
  21. import android.media.ImageReader;
  22. import android.os.Bundle;
  23. import android.os.Handler;
  24. import android.os.HandlerThread;
  25. import android.support.v4.app.ActivityCompat;
  26. import android.support.v4.content.ContextCompat;
  27. import android.util.Log;
  28. import android.util.Size;
  29. import android.view.Surface;
  30. import android.view.TextureView;
  31. import static com.mtcnn_as.ImageUtils.saveBitmap;
  32. public class Camera2Demo extends Activity implements
  33. TextureView.SurfaceTextureListener {
  34. private CameraDevice mCamera;
  35. private String mCameraID = "1";
  36. private TextureView mPreviewView;
  37. private Size mPreviewSize;
  38. private CaptureRequest.Builder mPreviewBuilder;
  39. private ImageReader mImageReader;
  40. private Handler mHandler;
  41. private HandlerThread mThreadHandler;
  42. // 这里定义的是ImageReader回调的图片的大小
  43. private int mImageWidth = 1920;
  44. private int mImageHeight = 1080;
  45. @Override
  46. public void onCreate(Bundle savedInstanceState) {
  47. super.onCreate(savedInstanceState);
  48. setContentView(R.layout.activity_texture);
  49. initView();
  50. initLooper();
  51. }
  52. // 很多过程都变成了异步的了,所以这里需要一个子线程的looper
  53. private void initLooper() {
  54. mThreadHandler = new HandlerThread("CAMERA2");
  55. mThreadHandler.start();
  56. mHandler = new Handler(mThreadHandler.getLooper());
  57. }
  58. // 可以通过TextureView或者SurfaceView
  59. private void initView() {
  60. mPreviewView = (TextureView) findViewById(R.id.textureView);
  61. mPreviewView.setSurfaceTextureListener(this);
  62. }
  63. @Override
  64. public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
  65. int height) {
  66. try {
  67. // 获得所有摄像头的管理者CameraManager
  68. CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
  69. // 获得某个摄像头的特征,支持的参数
  70. CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(mCameraID);
  71. // 支持的STREAM CONFIGURATION
  72. StreamConfigurationMap map = characteristics
  73. .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
  74. // 摄像头支持的预览Size数组
  75. mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
  76. if (ContextCompat.checkSelfPermission(Camera2Demo.this,
  77. Manifest.permission.CAMERA)
  78. != PackageManager.PERMISSION_GRANTED ||
  79. ContextCompat.checkSelfPermission(Camera2Demo.this,
  80. Manifest.permission.WRITE_EXTERNAL_STORAGE)
  81. != PackageManager.PERMISSION_GRANTED) {
  82. ActivityCompat.requestPermissions(Camera2Demo.this,
  83. new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
  84. }
  85. // 打开相机
  86. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
  87. // TODO: Consider calling
  88. // ActivityCompat#requestPermissions
  89. // here to request the missing permissions, and then overriding
  90. // public void onRequestPermissionsResult(int requestCode, String[] permissions,
  91. // int[] grantResults)
  92. // to handle the case where the user grants the permission. See the documentation
  93. // for ActivityCompat#requestPermissions for more details.
  94. return;
  95. }
  96. cameraManager.openCamera(mCameraID, mCameraDeviceStateCallback, mHandler);
  97. } catch (CameraAccessException e) {
  98. e.printStackTrace();
  99. }
  100. }
  101. @Override
  102. public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
  103. int height) {
  104. }
  105. @Override
  106. public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
  107. return false;
  108. }
  109. // 这个方法要注意一下,因为每有一帧画面,都会回调一次此方法
  110. @Override
  111. public void onSurfaceTextureUpdated(SurfaceTexture surface) {
  112. }
  113. private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
  114. @Override
  115. public void onOpened(CameraDevice camera) {
  116. try {
  117. mCamera = camera;
  118. startPreview(mCamera);
  119. } catch (CameraAccessException e) {
  120. e.printStackTrace();
  121. }
  122. }
  123. @Override
  124. public void onDisconnected(CameraDevice camera) {
  125. }
  126. @Override
  127. public void onError(CameraDevice camera, int error) {
  128. }
  129. };
  130. // 开始预览,主要是camera.createCaptureSession这段代码很重要,创建会话
  131. private void startPreview(CameraDevice camera) throws CameraAccessException {
  132. SurfaceTexture texture = mPreviewView.getSurfaceTexture();
  133. // 这里设置的就是预览大小
  134. texture.setDefaultBufferSize(mPreviewSize.getWidth(),mPreviewSize.getHeight());
  135. Surface surface = new Surface(texture);
  136. try {
  137. // 设置捕获请求为预览,这里还有拍照啊,录像等
  138. mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
  139. } catch (CameraAccessException e) {
  140. e.printStackTrace();
  141. }
  142. // 就是在这里,通过这个set(key,value)方法,设置曝光啊,自动聚焦等参数!! 如下举例:
  143. // mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
  144. mImageReader = ImageReader.newInstance(mImageWidth, mImageHeight,
  145. ImageFormat.JPEG/* 此处还有很多格式,比如我所用到YUV等 */, 2/*
  146. * 最大的图片数,
  147. * mImageReader里能获取到图片数
  148. * ,
  149. * 但是实际中是2+1张图片,就是多一张
  150. */);
  151. mImageReader.setOnImageAvailableListener(mOnImageAvailableListener,mHandler);
  152. // 这里一定分别add两个surface,一个Textureview的,一个ImageReader的,如果没add,会造成没摄像头预览,或者没有ImageReader的那个回调!!
  153. mPreviewBuilder.addTarget(surface);
  154. mPreviewBuilder.addTarget(mImageReader.getSurface());
  155. camera.createCaptureSession(
  156. Arrays.asList(surface, mImageReader.getSurface()),
  157. mSessionStateCallback, mHandler);
  158. }
  159. private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {
  160. @Override
  161. public void onConfigured(CameraCaptureSession session) {
  162. try {
  163. updatePreview(session);
  164. } catch (CameraAccessException e) {
  165. e.printStackTrace();
  166. }
  167. }
  168. @Override
  169. public void onConfigureFailed(CameraCaptureSession session) {
  170. }
  171. };
  172. private void updatePreview(CameraCaptureSession session)
  173. throws CameraAccessException {
  174. session.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
  175. }
  176. private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
  177. /**
  178. * 当有一张图片可用时会回调此方法,但有一点一定要注意: 一定要调用
  179. * reader.acquireNextImage()和close()方法,否则画面就会卡住!!!!!我被这个坑坑了好久!!!
  180. * 很多人可能写Demo就在这里打一个Log,结果卡住了,或者方法不能一直被回调。
  181. **/
  182. @Override
  183. public void onImageAvailable(ImageReader reader) {
  184. long startTime = System.currentTimeMillis(); //起始时间
  185. Image img = reader.acquireNextImage();
  186. /**
  187. * 因为Camera2并没有Camera1的Priview回调!!!所以该怎么能到预览图像的byte[]呢?就是在这里了!!!
  188. * 我找了好久的办法!!!
  189. **/
  190. ByteBuffer buffer = img.getPlanes()[0].getBuffer();
  191. // 这里就是图片的byte数组了
  192. byte[] bytes = new byte[buffer.remaining()];
  193. buffer.get(bytes);
  194. img.close();
  195. Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
  196. Matrix matrix = new Matrix();
  197. matrix.postRotate(270);
  198. // matrix.postScale( 1/2, 1/2); // 长和宽放大缩小的比例
  199. Bitmap bimap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
  200. int faceInfo[] = null;
  201. Bitmap rgba = bimap1.copy(Bitmap.Config.ARGB_8888, true);
  202. long endTime = System.currentTimeMillis(); //结束时间
  203. int width = rgba.getWidth();
  204. int height = rgba.getHeight();
  205. byte[] imageDate = getPixelsRGBA(rgba);
  206. long endTime2 = System.currentTimeMillis(); //结束时间
  207. saveBitmap(getApplicationContext(),rgba);
  208. Log.e("test", String.format("方法使用时间 %d %d ms", endTime - startTime,endTime2-startTime));
  209. }
  210. };
  211. //提取像素点
  212. private byte[] getPixelsRGBA(Bitmap image) {
  213. // calculate how many bytes our image consists of
  214. int bytes = image.getByteCount();
  215. ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
  216. image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer
  217. byte[] temp = buffer.array(); // Get the underlying array containing the
  218. return temp;
  219. }
  220. protected void onPause() {
  221. if (null != mCamera) {
  222. mCamera.close();
  223. mCamera = null;
  224. }
  225. if (null != mImageReader) {
  226. mImageReader.close();
  227. mImageReader = null;
  228. }
  229. super.onPause();
  230. }
  231. }

 

文章来源: blog.csdn.net,作者:网奇,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jacke121/article/details/101514590

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。