{"id":30,"date":"2015-03-31T10:11:04","date_gmt":"2015-03-31T10:11:04","guid":{"rendered":"https:\/\/boochlin.com\/?p=30"},"modified":"2026-09-16T09:54:22","modified_gmt":"2026-09-16T09:54:22","slug":"android-camera-analyze-%e4%b8%89-how-to-create-camera-2","status":"publish","type":"post","link":"https:\/\/boochlin.com\/?p=30","title":{"rendered":"Android Camera analyze (\u4e09) \u2013 How to create Camera 2."},"content":{"rendered":"<h3>How to create a camera 2<\/h3>\n<p>** <a href=\"\/\/www.slideshare.net\/boochlin\/camera2-how-tocreate\">How to create a camera2<\/a>**<\/p>\n<p>\u00a0<\/p>\n<h4>page2:<\/h4>\n<p><strong>How to create a camera 2.<\/strong><\/p>\n<p>Step1:To enumerate, query, and open available camera devices, obtain a CameraManager instance.<\/p>\n<p>\u5f9esystem\u53d6\u5f97cameraManager\u3002<\/p>\n<pre><code class=\"hljs language-plaintext\">\/\/ To get a list of available sizes of camera preview, we retrieve an instance of\n\/\/ StreamConfigurationMap from CameraCharacteristics\nCameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\nStreamConfigurationMap map = characteristics\n                    .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);\n (Camera.Size) mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];\n (SurfaceTexture) mTextureView.setAspectRatio(mPreviewSize.getWidth(), \n\/\/ We are opening the camera with a listener. When it is ready, onOpened of\n\/\/ (CameraDevice.StateListener)mStateListener is called.\nmanager.openCamera(cameraId, mStateListener, null);<\/code><\/pre>\n<h4>page3:<\/h4>\n<p><strong>Initialize CameraDevice:<\/strong><\/p>\n<p>Step2:Individual CameraDevices provide a set of static property information that describes the hardware device and the available settings and output parameters for the device.<\/p>\n<p>\u6839\u64dasystem \u53d6\u5f97 CameraCharacteristics \u53bb\u6e96\u5099\u958b\u555fCameraDevice<\/p>\n<pre><code class=\"hljs language-plaintext\">CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);\nmanager.openCamera(cameraId, mStateListener, null);<\/code><\/pre>\n<h4>page4:<\/h4>\n<p><strong>CameraDevice.StateListener:<\/strong><\/p>\n<p>A listener for notifications about the state of a camera device<\/p>\n<p>\u7e3d\u662f\u8981\u53bb\u76e3\u807ddevice\u662f\u5426\u958b\u555f\uff0c\u95dc\u9589\uff0c\u786c\u9ad4\u932f\u8aa4\u7b49\u7b49<\/p>\n<h4>page5:<\/h4>\n<p><strong>CameraDevice:<\/strong><\/p>\n<p>The CameraDevice class is a representation of a single camera connected to an Android device, allowing for fine-grain control of image capture and post-processing at high frame rates.<\/p>\n<p>Device is modeled as a pipeline<\/p>\n<p>\u91cd\u8981\u7684\u4e3b\u63a7\u7aef\uff0c\u8ca0\u8cac\u63a5\u6536\u6240\u6709callback \u548c\u5c0ddevice\u7684\u63a7\u5236<\/p>\n<p>\u662f\u4e00\u500bpipline\u7684\u6a21\u7d44\u3002\u7c21\u55ae\u4f86\u8aaa\u7684\u6d41\u7a0b<\/p>\n<p>Input : CaptureRequest for a single Frame<\/p>\n<p>Output: CaptureResult Metadata packet + output image buffers for the request. These buffers can go to one or multiple output targets.<\/p>\n<h4>page6:<\/h4>\n<p><strong>Start preview :<\/strong><\/p>\n<p>Step3:To capture or stream images from a camera device, the application must first create a camera capture session with a set of output Surfaces for use with the camera device.<\/p>\n<p>\u958b\u555f\u9810\u89bd\u756b\u9762\uff0c\u57fa\u672c\u4e0a\u53ef\u4ee5\u540c\u6642\u767c\u5230\u597d\u5e7e\u500bsurface<\/p>\n<p>\u9019\u88e1\u4ee5\u55ae\u4e00surface\u70ba\u4e3b\uff0c\u9019\u88e1\u8981\u8a18\u5f97\u958b\u555fcapturesession\u662f\u5fc5\u9808\u5305\u542b\u672a\u4f86\u6700\u5927\u5b50\u96c6\u9700\u8981\u7528\u5230\u7684surface<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ We configure the size of default buffer to be the size of camera preview we want.<\/span>\ntexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());\n<span class=\"hljs-comment\">\/\/ This is the output Surface we need to start preview.<\/span>\n<span class=\"hljs-type\">Surface<\/span> <span class=\"hljs-variable\">surface<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">Surface<\/span>(texture);\n<span class=\"hljs-comment\">\/\/ We set up a CaptureRequest.Builder with the output Surface.<\/span>\nmPreviewBuilder =  mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\nmPreviewBuilder.addTarget(surface);\n<span class=\"hljs-comment\">\/\/ Here, we create a CameraCaptureSession for camera preview.<\/span>\nmCameraDevice.createCaptureSession(Arrays.asList(surface),\n                    <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">CameraCaptureSession<\/span>.StateListener(){.....}<\/code><\/pre>\n<h4>page7:<\/h4>\n<p><strong>CaptureRequest.Builder:<\/strong><\/p>\n<p>\u2013 A builder for capture requests.<\/p>\n<p>\u2013 To obtain a builder instance, use the createCaptureRequest(int) method, which initializes the request fields to one of the templates defined in CameraDevice.<\/p>\n<p>\u6240\u6709\u7684request\u90fd\u5fc5\u9808\u7d93\u904e\u6307\u5b9a\u63d0\u4f9b\u7684builder\u7684\u63d0\u4f9b\uff0c\u9019\u5728\u4e0d\u5c11android\u7684\u8a2d\u8a08\u90fd\u662f\u9019\u6a23\u641e<\/p>\n<p>\u50cf\u662fnotification\u3002<\/p>\n<p>\u901a\u5e38\u8981\u5beb\u5165captureRequest\u7684field \u8a2d\u5b9a\u548c\u8f38\u51fa\u7684target surface.<\/p>\n<h4>page8:<\/h4>\n<p><strong>CaptureRequest:<\/strong><\/p>\n<p>\u2013 An immutable package of settings and outputs needed to capture a single image from the camera device.<\/p>\n<p>\u2013 Contains the configuration for the capture hardware (sensor, lens, flash), the processing pipeline, the control algorithms, and the output buffers. Also contains the list of target Surfaces to send image data to for this capture.<\/p>\n<p>\u2013 CaptureRequests can be created by using a CaptureRequest.Builder instance, obtained by calling createCaptureRequest(int)<\/p>\n<p>\u61f6\u5f97\u89e3\u91cb\u4e86\uff0c\u6839\u64da\u4e0a\u9801\uff0c\u505a\u51fa\u4f86\u7684request\u901a\u5e38\u6703\u6709\u5927\u91cf\u7684\u8cc7\u8a0a\uff0c\u4e00\u822c\u4f86\u8aaa1 request \u00a0\u5c0d\u61c91 image data<\/p>\n<p>\u9019\u4e5f\u662fcamera2 \u7684\u91cd\u8981\u7279\u8272\uff0c\u5728request \u4e2d\u53ef\u4ee5\u653e\u5165\u5404\u7a2e\u8a2d\u5b9a\u548c\u8f38\u51fasurface\uff0c\u6240\u4ee5\u53ef\u4ee5\u540c\u6642\u6709\u5f88\u591a\u7a2e\u8b8a\u5316\u5728\u5f88\u77ed\u7684\u6642\u9593(fps)<\/p>\n<h4>page9:<\/h4>\n<p><strong>CameraCaptureSession.StateListener:<\/strong><\/p>\n<p>A listener for tracking the state of a camera capture session.<\/p>\n<p>\u9664\u4e86\u4e4b\u524d\u7684cameradevice\u76e3\u63a7\uff0c\u4e4b\u5916\u9084\u8981\u76e3\u63a7capturesession\u72c0\u6cc1<\/p>\n<p>\u524d\u8ff0\u6709\u63d0\u904e\uff0c\u7576\u958b\u555fcameraDevice\u9084\u662f\u8981\u958b\u555f\u5c08\u9580\u7684session\u53bb\u57f7\u884c<\/p>\n<p>captureSession\u7684\u8a73\u7d30\u5167\u5bb9\u53ef\u4ee5\u53c3\u8003\u4e0b\u4e00\u9801<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title function_\">onConfigured<\/span><span class=\"hljs-params\">(CameraCaptureSession cameraCaptureSession)<\/span> {\n             <span class=\"hljs-comment\">\/\/ When the session is ready, we start displaying the preview.<\/span>\n             mPreviewSession = cameraCaptureSession;\n             <span class=\"hljs-comment\">\/\/ In this sample, we just let the camera device pick the automatic settings.<\/span>\n\t\t     mPreviewBuilder.set(CaptureRequest.CONTROL_MODE\n\t\t\t\t, CameraMetadata.CONTROL_MODE_AUTO);\n             <span class=\"hljs-type\">HandlerThread<\/span> <span class=\"hljs-variable\">thread<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">HandlerThread<\/span>(<span class=\"hljs-string\">&quot;CameraPreview&quot;<\/span>);\n            thread.start();\n            <span class=\"hljs-type\">Handler<\/span> <span class=\"hljs-variable\">backgroundHandler<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">Handler<\/span>(thread.getLooper());\n            <span class=\"hljs-comment\">\/\/ Finally, we start displaying the camera preview.<\/span>\n            mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), <span class=\"hljs-literal\">null<\/span>, backgroundHandler);\n       }<\/code><\/pre>\n<h4>page10:<\/h4>\n<p><strong>CameraCaptureSession:<\/strong><\/p>\n<p>\u2013 A configured capture session for a CameraDevice, used for capturing images from the camera.<\/p>\n<p>\u2013 A CameraCaptureSession is created by providing a set of target output surfaces to createCaptureSession. Once created, the session is active until a new session is created by the camera device, or the camera device is closed.<\/p>\n<p>CaptureSession\u7684\u5e7e\u500bapi\u5f88\u660e\u986f\u5c31\u662f\u4f86\u89e3\u6c7a zero shutter lag\uff0c\u81ea\u5df1\u611f\u53d7\u611f\u53d7<\/p>\n<pre><code class=\"hljs language-plaintext\">capture(CaptureRequest request, CameraCaptureSession.CaptureListener listener, Handler handler)\nSubmit a request for an image to be captured by the camera device.\n\ncaptureBurst(List requests, CameraCaptureSession.CaptureListener listener, Handler handler)\nSubmit a list of requests to be captured in sequence as a burst.\n\nsetRepeatingBurst(List requests, CameraCaptureSession.CaptureListener listener, Handler handler)\nRequest endlessly repeating capture of a sequence of images by this capture session.\n\nsetRepeatingRequest(CaptureRequest request, CameraCaptureSession.CaptureListener listener, Handler handler)\nRequest endlessly repeating capture of images by this capture session.<\/code><\/pre>\n<p>\u4e0d\u5f97\u4e0d\u8aaa\u90a3\u500bburst\u6839\u672c\u5c31\u662fburst\uff0c\u81ea\u5df1\u5beb\u904e\u5e7e\u6b21\u5c31\u77e5\u9053\u5566\uff0c\u4e0d\u904e\u8981\u771f\u7684\u5feb\u7684\u8a71\u76ee\u524d\u53ea\u6709nexus 9 \u548c 6\u3002<\/p>\n<h4>page11:<\/h4>\n<p><strong>Take picture1:<\/strong><\/p>\n<p>Step4: Capture of JPEG images or RAW buffers for Dng Creator can be done with ImageReader with the {android.graphics.ImageFormat#JPEG} and {android.graphics.ImageFormat#RAW_SENSOR} formats.<\/p>\n<p>raw buffer \u00a0\u662fcamera2 \u624d\u652f\u63f4\uff5e\uff5e<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-type\">CameraManager<\/span> <span class=\"hljs-variable\">manager<\/span> <span class=\"hljs-operator\">=<\/span>\n            (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\n<span class=\"hljs-comment\">\/\/ Pick the best JPEG size that can be captured with this CameraDevice.<\/span>\n<span class=\"hljs-type\">CameraCharacteristics<\/span> <span class=\"hljs-variable\">characteristics<\/span> <span class=\"hljs-operator\">=<\/span>\nmanager.getCameraCharacteristics(mCameraDevice.getId());\n<span class=\"hljs-type\">Size<\/span>[] <span class=\"hljs-variable\">jpegSizes<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-literal\">null<\/span>;\n<span class=\"hljs-keyword\">if<\/span> (characteristics != <span class=\"hljs-literal\">null<\/span>) {\n           jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) .getOutputSizes(ImageFormat.JPEG);\n   }\n <span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">width<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">640<\/span>; <span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">height<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-number\">480<\/span>;\n <span class=\"hljs-keyword\">if<\/span> (jpegSizes != <span class=\"hljs-literal\">null<\/span> &amp;&amp; <span class=\"hljs-number\">0<\/span> &lt; jpegSizes.length) {\n            width = jpegSizes[<span class=\"hljs-number\">0<\/span>].getWidth();\n             height = jpegSizes[<span class=\"hljs-number\">0<\/span>].getHeight();\n    }\n\n<span class=\"hljs-comment\">\/\/ This is the CaptureRequest.Builder that we use to take a picture.<\/span>\n<span class=\"hljs-keyword\">final<\/span> CaptureRequest.<span class=\"hljs-type\">Builder<\/span> <span class=\"hljs-variable\">captureBuilder<\/span> <span class=\"hljs-operator\">=<\/span>\nmCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);\ncaptureBuilder.addTarget(reader.getSurface());\n<span class=\"hljs-comment\">\/\/ In this sample, we just let the camera device pick the automatic settings. captureBuilder.set(CaptureRequest.CONTROL_MODE,CameraMetadata.CONTROL_MODE_AUTO);<\/span><\/code><\/pre>\n<h4>page12:<\/h4>\n<p><strong>\u627f\u4e0a takePicture2<\/strong><\/p>\n<p>Step5:Use ImageReader to get output data<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ We use an ImageReader to get a JPEG from CameraDevice.<\/span>\n<span class=\"hljs-comment\">\/\/ Here, we create a new ImageReader and prepare its Surface as an output from camera.<\/span>\n<span class=\"hljs-type\">ImageReader<\/span> <span class=\"hljs-variable\">reader<\/span> <span class=\"hljs-operator\">=<\/span> ImageReader.newInstance(width, height, ImageFormat.JPEG, <span class=\"hljs-number\">1<\/span>);\n<span class=\"hljs-type\">List<\/span> <span class=\"hljs-variable\">outputSurfaces<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">ArrayList<\/span>(<span class=\"hljs-number\">2<\/span>);\noutputSurfaces.add(reader.getSurface());\noutputSurfaces.add(<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">Surface<\/span>(mTextureView.getSurfaceTexture()));\n\n<span class=\"hljs-comment\">\/\/ This is the CaptureRequest.Builder that we use to take a picture.<\/span>\n<span class=\"hljs-keyword\">final<\/span> CaptureRequest.<span class=\"hljs-type\">Builder<\/span> <span class=\"hljs-variable\">captureBuilder<\/span> <span class=\"hljs-operator\">=<\/span>\nmCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);\ncaptureBuilder.addTarget(reader.getSurface());\n<span class=\"hljs-comment\">\/\/ In this sample, we just let the camera device pick the automatic settings. captureBuilder.set(CaptureRequest.CONTROL_MODE,CameraMetadata.CONTROL_MODE_AUTO);<\/span><\/code><\/pre>\n<h4>page13:<\/h4>\n<p><strong>ImageReader:<\/strong><\/p>\n<p>The ImageReader class allows direct application access to image data rendered into a Surface<\/p>\n<p>\u70ba\u4e00\u7a2e\u66ab\u5b58\u7684 image data buffer consumer. \u6bd4\u8f03\u7279\u5225\u7684\u662f\u6709size\u53ef\u4ee5\u8a2d\u5b9a\uff0capi19\u524d\u5e7e\u4e4e\u6c92\u6709\u3002<\/p>\n<h4>page14:<\/h4>\n<p><strong>Take picture3<\/strong><\/p>\n<p>Step6:Set output data parameters.<\/p>\n<p>\u6b64\u968e\u6bb5\u540c\u6642\u8a2d\u5b9a image reader listener\uff0c\u7528\u4f86\u63a5\u6536device\u767c\u51fa\u7684\u8cc7\u6599\u3002<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ In this sample, we just let the camera device pick the automatic settings.<\/span>\ncapturebuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);\n<span class=\"hljs-comment\">\/\/ Orientation<\/span>\n<span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">rotation<\/span> <span class=\"hljs-operator\">=<\/span> activity.getWindowManager().getDefaultDisplay().getRotation();\ncaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));\n<span class=\"hljs-comment\">\/\/ Output file<\/span>\n<span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">File<\/span> <span class=\"hljs-variable\">file<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">File<\/span>(activity.getExternalFilesDir(<span class=\"hljs-literal\">null<\/span>), <span class=\"hljs-string\">&quot;pic.jpg&quot;<\/span>);\n<span class=\"hljs-comment\">\/\/ This listener is called when a image is ready in ImageReader<\/span>\nImageReader.<span class=\"hljs-type\">OnImageAvailableListener<\/span> <span class=\"hljs-variable\">readerListener<\/span> <span class=\"hljs-operator\">=<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">ImageReader<\/span>.OnImageAvailableListener() {\u2026.}<\/code><\/pre>\n<h4>page15:<\/h4>\n<p><strong>ImageReader.OnImageAvailableListener<\/strong><\/p>\n<p>Callback interface for being notified that a new image is available.<\/p>\n<pre><code class=\"hljs language-java\">onImageAvailable(ImageReader reader) {\u00a0\nimage = reader.acquireLatestImage();\n<span class=\"hljs-type\">ByteBuffer<\/span> <span class=\"hljs-variable\">buffer<\/span> <span class=\"hljs-operator\">=<\/span> image.getPlanes()[<span class=\"hljs-number\">0<\/span>].getBuffer();\n<span class=\"hljs-type\">byte<\/span>[] <span class=\"hljs-variable\">bytes<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">byte<\/span>[buffer.capacity()];\nbuffer.get(bytes);\nsave(bytes);\n\u2026..<span class=\"hljs-comment\">\/\/Use output stream to write out to file.<\/span>\n\u2026\u2026\nImage.close();<\/code><\/pre>\n<h4>page16:<\/h4>\n<p><strong>Take picture4<\/strong><\/p>\n<p>Step7:Set output data parameters. And start camera capture picture thread.\u00a0<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ In this sample, we just let the camera device pick the automatic settings.<\/span>\ncapturebuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);\n<span class=\"hljs-comment\">\/\/ Orientation<\/span>\n<span class=\"hljs-type\">int<\/span> <span class=\"hljs-variable\">rotation<\/span> <span class=\"hljs-operator\">=<\/span> activity.getWindowManager().getDefaultDisplay().getRotation();\ncaptureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));\n<span class=\"hljs-comment\">\/\/ Output file<\/span>\n<span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">File<\/span> <span class=\"hljs-variable\">file<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">File<\/span>(activity.getExternalFilesDir(<span class=\"hljs-literal\">null<\/span>), <span class=\"hljs-string\">&quot;pic.jpg&quot;<\/span>);\n<span class=\"hljs-comment\">\/\/ This listener is called when a image is ready in ImageReader<\/span>\n ImageReader.<span class=\"hljs-type\">OnImageAvailableListener<\/span> <span class=\"hljs-variable\">readerListener<\/span> <span class=\"hljs-operator\">=<\/span>\n               <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">ImageReader<\/span>.OnImageAvailableListener() {\u2026.}\n<span class=\"hljs-comment\">\/\/ We create a Handler since we want to handle the result JPEG in a background thread<\/span>\n<span class=\"hljs-type\">HandlerThread<\/span> <span class=\"hljs-variable\">thread<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">HandlerThread<\/span>(<span class=\"hljs-string\">&quot;CameraPicture&quot;<\/span>);\nthread.start();\n<span class=\"hljs-keyword\">final<\/span> <span class=\"hljs-type\">Handler<\/span> <span class=\"hljs-variable\">backgroundHandler<\/span> <span class=\"hljs-operator\">=<\/span> <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">Handler<\/span>(thread.getLooper());\nreader.setOnImageAvailableListener(readerListener, backgroundHandler);<\/code><\/pre>\n<h4>page17:<\/h4>\n<p><strong>takePicture5<\/strong><\/p>\n<p>Step8:Restart preview thread after capture complete.<\/p>\n<p>\u9019\u88e1\u662f\u6709\u9806\u5e8f\u7684\uff0c\u518dcapturesession listener \u7684 capture complete \u5f8c\u91cd\u8d77startpreview()<\/p>\n<p>\u5148\u8aaa\u9019\u500bstartpreview()\u4e0d\u662fcamera1\u7684api \uff0c\u800c\u662f\u4e4b\u524d\u6211\u5011\u81ea\u5df1\u5beb\u7684 startpreview()<\/p>\n<p>\u4ee5\u767c\u751f\u6642\u9593\u4f86\u6392\u5e8f\u662f\u53f3\u908a\u5148 \u5de6\u908a\u5f8c<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ Finally, we can start a new CameraCaptureSession to take a picture. mCameraDevice.createCaptureSession(outputSurfaces,<\/span>\n<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">CameraCaptureSession<\/span>.StateListener() {\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title function_\">onConfigured<\/span><span class=\"hljs-params\">(CameraCaptureSession session)<\/span> {\n\t<span class=\"hljs-keyword\">try<\/span> {\n\t\tsession.capture(captureBuilder.build(), captureListener,\n                                        backgroundHandler);\n\t} <span class=\"hljs-keyword\">catch<\/span> (CameraAccessException e) {\n\t\te.printStackTrace();\n\t}\n     }\n}, backgroundHandler );<\/code><\/pre>\n<p>then<\/p>\n<pre><code class=\"hljs language-java\"><span class=\"hljs-comment\">\/\/ This listener is called when the capture is completed.<\/span>\n<span class=\"hljs-comment\">\/\/ Note that the JPEG data is not available in this listener, but in the<\/span>\n <span class=\"hljs-comment\">\/\/ ImageReader.OnImageAvailableListener we created above.<\/span>\n <span class=\"hljs-keyword\">final<\/span> CameraCaptureSession.<span class=\"hljs-type\">CaptureListener<\/span> <span class=\"hljs-variable\">captureListener<\/span> <span class=\"hljs-operator\">=<\/span>\n\t<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-title class_\">CameraCaptureSession<\/span>.CaptureListener() {\n\t<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-type\">void<\/span> <span class=\"hljs-title function_\">onCaptureCompleted<\/span><span class=\"hljs-params\">(CameraCaptureSession session,\n\tCaptureRequest request,   TotalCaptureResult result)<\/span> {\n          <span class=\"hljs-comment\">\/\/ We restart the preview when the capture is completed<\/span>\n                            startPreview();\n\t\t\t}\n\t\t};<\/code><\/pre>\n<p>\u4ee5\u4e0a\u662fCamera2\u7684takePicture\u7c21\u6613\u5be6\u4f5c\u904e\u7a0b\uff0c\u6700\u91cd\u8981\u7684\u9084\u662f\u627e\u5230\u4e00\u53f0\u53ef\u4ee5\u8dd1hal3\u7684\u6a5f\u5668<\/p>\n<p> \u4e0d\u7136\u5f88\u591a\u529f\u80fd\u90fd\u662f\u95dc\u6389\u7684\uff0c\u7d50\u679c\u5c31\u6703\u50cf\u662f\u53ea\u662f\u63db\u500b\u5beb\u6cd5\u5bebcamera1<\/p>\n<p>\u5b8c\u6574\u7a0b\u5f0f\u78bc<\/p>\n<p><a href=\"https:\/\/github.com\/googlesamples\/android-Camera2Basic\">https:\/\/github.com\/googlesamples\/android-Camera2Basic<\/a><\/p>\n<p>google i\/o \u4ecb\u7d39<\/p>\n<p><a href=\"https:\/\/www.google.com\/events\/io\">https:\/\/www.google.com\/events\/io<\/a><\/p>\n<p>\u4ee5\u4e0b\u662f\u4e00\u4e9b\u53ef\u80fd\u770b\u6295\u5f71\u7247\u6216\u662f\u958b\u767c\u6642\u60f3\u4e0d\u900f\u7684\u90e8\u4efd\u505a\u6210QA<\/p>\n<h4><strong>Q1:synchronize?<\/strong><\/h4>\n<p>A1:\u65b0\u7684capture request \u540c\u6642\u5305\u542bparameter\u7684setting\u548ccapture \u7684\u884c\u70ba\uff0c\u4e26\u57f7\u884c\u65bccamera device\u7aef\uff0c\u904e\u53bbold camera \u5247\u662f\u5c07\u9019\u5169\u500b\u884c\u70ba\u5206\u958b\u4e26\u7531ap\u7aef\u53bbcontrol\u3002<\/p>\n<pre class=\"mermaid\">sequenceDiagram\n    autonumber\n    box rgb(240, 240, 240) \u820a\u7248 Camera1 (\u975e\u540c\u6b65\u5206\u958b\u63a7\u5236\uff0c\u6613 Race Condition)\n    actor App1 as App Client\n    participant Cam1 as Camera Service\n    end\n    App1->>Cam1: setParameters(params)\n    App1->>Cam1: takePicture() (\u53c3\u6578\u8207\u5feb\u9580\u4e0d\u540c\u6b65)\n\n    box rgb(230, 245, 255) \u65b0\u7248 Camera2 (\u55ae\u4e00 CaptureRequest \u539f\u5b50\u7d81\u5b9a)\n    actor App2 as App Client\n    participant Pipe as CameraCaptureSession\n    participant HAL as CameraDevice (HAL3)\n    end\n    App2->>Pipe: capture(CaptureRequest[Parameters + Target Surfaces])\n    Pipe->>HAL: \u539f\u5b50\u7ba1\u7dda\u5206\u767c\uff1a\u55ae\u5e40\u66dd\u5149\u53c3\u6578\u8207\u5f71\u50cf\u5b8c\u5168\u540c\u6b65<\/pre>\n<h4><\/h4>\n<pre class=\"mermaid\">graph TD\n    App[\u61c9\u7528\u7a0b\u5f0f App] -->|1. \u8acb\u6c42\u8a2d\u5099| CM[CameraManager]\n    CM -->|2. \u958b\u555f\u8a2d\u5099| CD[CameraDevice]\n    CD -->|3. \u5efa\u7acb\u7ba1\u7dda| CCS[CameraCaptureSession]\n    CCS -->|4. \u63d0\u4ea4\u8acb\u6c42| CR[CaptureRequest]\n    CR -->|Surface 1| SV[SurfaceView \u9810\u89bd\u8f38\u51fa]\n    CR -->|Surface 2| IR[ImageReader AI \u5206\u6790\u6d41]\n    CR -->|Surface 3| MR[MediaRecorder \u9304\u5f71\u7de8\u78bc]<\/pre>\n<h4><strong>Q2:\u70ba\u4f55\u70ba\u4f55 captureSession \u6642\uff0c\u6703\u653e\u5165outputSurface(Surface[]) \u591a\u500bsurface \u800c\u4e26\u975e\u6307\u5b9a\u55ae\u4e00surface?<\/strong><\/h4>\n<p>A2:\u518d\u5275\u5efaCameraCaptureSession \u901a\u5e38\u6703\u653e\u5165\u672a\u4f86\u53ef\u80fd\u6703\u7528\u5230\u7684target surfaces \uff0c\u4e26\u4e0d\u6703\u53ea\u653e\u5165\u55ae\u4e00\u7684target surface \uff0c\u800c\u55ae\u4e00\u6307\u5b9asurface \u7684\u9700\u6c42\u5beb\u5165capture request\u88e1<\/p>\n<h4><strong>Q3:ImageReader \u4f7f\u7528\u65b9\u6cd5\uff1f<\/strong><\/h4>\n<p>A3:Use ImageReader.getSurface() to get a Surface that can be used to produce Images for this ImageReader.<\/p>\n<h4><strong>Q3-1:what is surface?<\/strong><\/h4>\n<p>A3-1:<\/p>\n<p>1.Handle onto a raw buffer that is being managed by the screen compositor.<\/p>\n<ol start=\"2\">\n<li>surface \u7684canvas\u6210\u54e1\u53ef\u4ee5\u7528\u4f86\u63d0\u4f9b\u7e6a\u5716\u7684\u5834\u6240\uff0craw buffer \u7528\u4f86\u4fdd\u5b58data \uff0c\u53d6\u5f97surface \u7b49\u540c\u53d6\u5f97canvas \u548c raw buffer\u7684\u5167\u5bb9\u3002<\/li>\n<\/ol>\n<p>summary: \u65bccamera ap \u88e1\u5247\u662f\u7b49\u540c\u63d0\u4f9bcapture\u8f38\u51fadata\u7684\u7684\u76ee\u6a19surface\uff0c\u63a5\u8005imagereader\u6703\u5f9esurface \u53bb\u5c01\u88dddata\u8b8a\u6210image class\u3002<\/p>\n<p>\u4e0b\u4e00\u7ae0\u7bc0\u6703\u4f86\u63a2\u8a0e Camera2 framework.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to create a camera 2 ** How to create a camera2** \u00a0 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[167],"tags":[193,196],"_links":{"self":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts\/30"}],"collection":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=30"}],"version-history":[{"count":4,"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts\/30\/revisions"}],"predecessor-version":[{"id":1427,"href":"https:\/\/boochlin.com\/index.php?rest_route=\/wp\/v2\/posts\/30\/revisions\/1427"}],"wp:attachment":[{"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=30"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=30"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/boochlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=30"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}