{"id":1118,"date":"2019-03-04T21:09:13","date_gmt":"2019-03-04T12:09:13","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=1118"},"modified":"2020-01-30T10:52:00","modified_gmt":"2020-01-30T01:52:00","slug":"camera2-basic-%ec%86%8c%ec%8a%a4-%ec%82%b4%ed%8e%b4%eb%b3%b4%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=1118","title":{"rendered":"Camera2 Basic \uc18c\uc2a4 \uc0b4\ud3b4\ubcf4\uae30"},"content":{"rendered":"<p>&nbsp;<\/p>\n<h1>\uce74\uba54\ub77c<\/h1>\n<p>Android\uc758 \uce74\uba54\ub77c HAL (Hardware Abstraction Layer)\uc740 Camera 2\uc758 \uc0c1\uc704 \uc218\uc900\uc758 \uce74\uba54\ub77c \ud504\ub808\uc784 \uc6cc\ud06c API\ub97c \uae30\ubcf8 \uce74\uba54\ub77c \ub4dc\ub77c\uc774\ubc84 \ubc0f \ud558\ub4dc\uc6e8\uc5b4\uc5d0 \uc5f0\uacb0\ud569\ub2c8\ub2e4. \uce74\uba54\ub77c \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc740 \uce74\uba54\ub77c \ud30c\uc774\ud504 \ub77c\uc778 \uad6c\uc131 \uc694\uc18c\uc5d0 \ub300\ud55c \uad6c\ud604\uc744 \ud3ec\ud568\ud558\ub294 \ubc18\uba74 \uce74\uba54\ub77c HAL\uc740 \uc774\ub7ec\ud55c \uad6c\uc131 \uc694\uc18c\uc758 \ubc84\uc804\uc744 \uad6c\ud604\ud558\ub294 \ub370 \uc0ac\uc6a9\ud560 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/p>\n<h1>\uad6c\uc870<\/h1>\n<p>\ub2e4\uc74c \uadf8\ub9bc\uacfc \ubaa9\ub85d\uc740 HAL \uad6c\uc131 \uc694\uc18c\ub97c \uc124\uba85\ud569\ub2c8\ub2e4.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/source.android.com\/devices\/camera\/images\/ape_fwk_camera2.png\" alt=\"Android camera architecture\" id=\"figure1\" \/><\/p>\n<h2>Application Framework<\/h2>\n<p>Application Framework \uacc4\uce35\uc5d0\uc11c\ub294 <a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/package-summary\">Camera2<\/a> API\ub97c \uc0ac\uc6a9\ud558\uc5ec \uce74\uba54\ub77c \ud558\ub4dc\uc6e8\uc5b4\uc640 \uc0c1\ud638 \uc791\uc6a9\ud558\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ucf54\ub4dc\uac00 \uc788\uc2b5\ub2c8\ub2e4. \ub0b4\ubd80\uc801\uc73c\ub85c \uc774 \ucf54\ub4dc\ub294 \ud574\ub2f9 <a href=\"https:\/\/developer.android.com\/reference\/android\/os\/Binder.html\">\ubc14\uc778\ub354<\/a> \uc778\ud130\ud398\uc774\uc2a4\ub97c \ud638\ucd9c\ud558\uc5ec \uce74\uba54\ub77c\uc640 \uc0c1\ud638 \uc791\uc6a9\ud558\ub294 \ub124\uc774\ud2f0\ube0c \ucf54\ub4dc\uc5d0 \uc561\uc138\uc2a4\ud569\ub2c8\ub2e4.<\/p>\n<h2>AIDL<\/h2>\n<p>CameraService\uc640 \uad00\ub828\ub41c \ubc14\uc778\ub354 \uc778\ud130\ud398\uc774\uc2a4\ub294 <a href=\"https:\/\/android.googlesource.com\/platform\/frameworks\/av\/+\/master\/camera\/aidl\/android\/hardware\/ICameraService.aidl\">frameworks \/ av \/ camera \/ aidl \/ android \/ hardware<\/a>\uc5d0\uc11c \ucc3e\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc0dd\uc131 \ub41c \ucf54\ub4dc\ub294 \ud558\uc704 \uacc4\uce35\uc758 \ub124\uc774\ud2f0\ube0c \ucf54\ub4dc\ub97c \ud638\ucd9c\ud558\uc5ec \uc2e4\uc81c \uce74\uba54\ub77c\uc5d0 \uc561\uc138\uc2a4\ud558\uace0 \ud504\ub808\uc784 \uc6cc\ud06c \uacc4\uce35\uc5d0\uc11c <a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/CameraDevice\">CameraDevice<\/a> \ubc0f <a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/CameraCaptureSession.html\">CameraCaptureSession<\/a> \uac1d\uccb4\ub97c \ub9cc\ub4dc\ub294 \ub370 \uc0ac\uc6a9\ub418\ub294 \ub370\uc774\ud130\ub97c \ubc18\ud658\ud569\ub2c8\ub2e4.<\/p>\n<h2>Native Framework<\/h2>\n<p>frameworks \/ av \/\uc5d0 \uc788\ub294 \uc774 \ud504\ub808\uc784\uc6cc\ud06c\ub294 <a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/CameraDevice\">CameraDevice<\/a> \ubc0f <a href=\"https:\/\/developer.android.com\/reference\/android\/hardware\/camera2\/CameraCaptureSession\">CameraCaptureSession<\/a> \ud074\ub798\uc2a4\uc640 \ub3d9\ub4f1\ud55c \uace0\uc720\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4. <a href=\"https:\/\/developer.android.com\/ndk\/reference\/group\/camera\">NDK Camera2<\/a>\ub3c4 \ud655\uc778\ud574\ubcf4\uc138\uc694.<\/p>\n<h2><span>Binder IPC interface<\/span><\/h2>\n<p>IPC \ubc14\uc778\ub354 \uc778\ud130\ud398\uc774\uc2a4\ub294 \ud504\ub85c\uc138\uc2a4\uac04 \ud1b5\uc2e0\uc744 \uc6a9\uc774\ud558\uac8c\ud569\ub2c8\ub2e4. \uce74\uba54\ub77c \uc11c\ube44\uc2a4\ub97c \ud638\ucd9c\ud558\ub294 framework \/ av \/ camera \/ camera \/ aidl \/ android \/ hardware \ub514\ub809\ud1a0\ub9ac\uc5d0 \uc5ec\ub7ec \uce74\uba54\ub77c \ubc14\uc778\ub354 \ud074\ub798\uc2a4\uac00 \uc788\uc2b5\ub2c8\ub2e4. <a href=\"https:\/\/android.googlesource.com\/platform\/frameworks\/av\/+\/master\/camera\/aidl\/android\/hardware\/ICameraService.aidl\">ICameraService<\/a>\ub294 \uce74\uba54\ub77c \uc11c\ube44\uc2a4\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\uc785\ub2c8\ub2e4. <a href=\"https:\/\/android.googlesource.com\/platform\/frameworks\/av\/+\/master\/camera\/aidl\/android\/hardware\/camera2\/ICameraDeviceUser.aidl\">ICameraDeviceUser<\/a>\ub294 \ud2b9\uc815 \uc5f4\ub9b0 \uce74\uba54\ub77c \uc7a5\uce58\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\uc785\ub2c8\ub2e4. <a href=\"https:\/\/android.googlesource.com\/platform\/frameworks\/av\/+\/master\/camera\/aidl\/android\/hardware\/ICameraServiceListener.aidl\">ICameraServiceListener<\/a> \ubc0f <a href=\"https:\/\/android.googlesource.com\/platform\/frameworks\/av\/+\/master\/camera\/aidl\/android\/hardware\/camera2\/ICameraDeviceCallbacks.aidl\">ICameraDeviceCallbacks<\/a>\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud504\ub808\uc784 \uc6cc\ud06c\uc5d0 \ub300\ud55c \uac01\uac01\uc758 CameraService \ubc0f CameraDevice \ucf5c\ubc31\uc785\ub2c8\ub2e4.<\/p>\n<h2>Camera service<\/h2>\n<p>frameworks \/ av \/ services \/ camera \/ libcameraservice \/ CameraService.cpp\uc5d0\uc788\ub294 \uce74\uba54\ub77c \uc11c\ube44\uc2a4\ub294 HAL\uacfc \uc0c1\ud638 \uc791\uc6a9\ud558\ub294 \uc2e4\uc81c \ucf54\ub4dc\uc785\ub2c8\ub2e4.<\/p>\n<h2>HAL<\/h2>\n<p>\ud558\ub4dc\uc6e8\uc5b4 \ucd94\uc0c1\ud654 \ub808\uc774\uc5b4\ub294 \uce74\uba54\ub77c \uc11c\ube44\uc2a4\uac00 \ud638\ucd9c\ud558\ub294 \ud45c\uc900 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc815\uc758\ud558\uba70 \uce74\uba54\ub77c \ud558\ub4dc\uc6e8\uc5b4\uac00 \uc62c\ubc14\ub974\uac8c \uc791\ub3d9\ud558\ub3c4\ub85d \uad6c\ud604\ud574\uc57c\ud569\ub2c8\ub2e4.<\/p>\n<h3>WorkFlow<\/h3>\n<p><a href=\"https:\/\/www.charlezz.com\/?attachment_id=1119\" rel=\"attachment wp-att-1119\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/camera_model.png\" alt=\"\" width=\"914\" height=\"806\" class=\"aligncenter size-full wp-image-1119\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/camera_model.png 914w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/camera_model-300x265.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/camera_model-768x677.png 768w\" sizes=\"(max-width: 914px) 100vw, 914px\" \/><\/a><\/p>\n<p>Camera2\ub97c \uc0ac\uc6a9\ud558\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uae30\ubcf8\uc801\uc778 \uc6cc\ud06c\ud50c\ub85c\uc6b0\uc785\ub2c8\ub2e4. Camera\uc640 \ube44\uad50\ud558\uba74 \ubcf5\uc7a1\ud558\uc9c0\ub9cc, \uadf8\ub807\uac8c \uc5b4\ub835\uc9c0\ub294 \uc54a\uc2b5\ub2c8\ub2e4. \uad6c\uae00 \uc0d8\ud50c \uc608\uc81c\uc640 \ud568\uaed8 \ucc28\uadfc\ucc28\uadfc \uc0b4\ud3b4\ubcf4\ub3c4\ub85d \ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<h1>Camera2 Basic \uc0b4\ud3b4\ubcf4\uae30<\/h1>\n<p>\uc18c\uc2a4:<a href=\"https:\/\/github.com\/googlesamples\/android-Camera2Basic\">https:\/\/github.com\/googlesamples\/android-Camera2Basic<\/a><\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/?attachment_id=1123\" rel=\"attachment wp-att-1123\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2019-03-04-\u110b\u1169\u1112\u116e-8.34.06.png\" alt=\"\" width=\"1019\" height=\"619\" class=\"aligncenter size-full wp-image-1123\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2019-03-04-\u110b\u1169\u1112\u116e-8.34.06.png 1019w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2019-03-04-\u110b\u1169\u1112\u116e-8.34.06-300x182.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2019-03-04-\u110b\u1169\u1112\u116e-8.34.06-768x467.png 768w\" sizes=\"(max-width: 1019px) 100vw, 1019px\" \/><\/a><\/p>\n<p>Camera\uc640\ub294 \ub2ec\ub9ac Camera2\ub294 \uce74\uba54\ub77c\ub97c \uc5f4\uace0 \ud504\ub9ac\ubdf0\ub97c \uc5bb\uae30\uae4c\uc9c0 \ubaa8\ub4e0 \uc0c1\ud669\uc774 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 \ucf5c\ubc31\uc774 \ub9ce\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">@Override\r\npublic void onResume() {\r\n    super.onResume();\r\n    startBackgroundThread();\r\n    if (mTextureView.isAvailable()) {\r\n        openCamera(mTextureView.getWidth(), mTextureView.getHeight());\r\n    } else {\r\n        mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);\r\n    }\r\n}<\/pre>\n<p>\uc561\ud2f0\ube44\ud2f0(\ud504\ub808\uadf8\uba3c\ud2b8)\uac00 \uc2e4\ud589\uc774 \ub418\uba74 onResume()\uc774 \ud638\ucd9c\ub429\ub2c8\ub2e4. \uce74\uba54\ub77c\uc640 \uad00\ub828\ub41c \uc791\uc5c5\uc740 UI\ub97c \uadf8\ub9ac\ub294 \uba54\uc778\uc4f0\ub808\ub4dc\ub97c \ubc29\ud574\ud574\uc9c0 \uc54a\uae30 \uc704\ud574 onResume\uc5d0\uc11c \uc0c8\ub85c\uc6b4 \uc4f0\ub808\ub4dc\uc640 \ud578\ub4e4\ub7ec\ub97c \uc0dd\uc131\ud569\ub2c8\ub2e4. \ub610\ud55c Fragment\uc5d0 \ud3ec\ud568\ub41c TextureView \ub610\ud55c \uc778\ud50c\ub808\uc774\ud305\uacfc \ub3d9\uc2dc\uc5d0 \ucd08\uae30\ud654\uac00 \uc9c4\ud589\ub429\ub2c8\ub2e4.\u00a0<\/p>\n<p>\uc77c\ubc18\uc801\uc73c\ub85c \ucc98\uc74c \uc561\ud2f0\ube44\ud2f0\uac00 \uc2dc\uc791\ub418\uba74 \uc704\uc758 \uc870\uac74\ubb38\uc5d0\uc11c \ub450\ubc88\uc9f8\uc758 else\uc870\uac74\uc744 \ud0c0\uc9c0\ub9cc, \ub2e4\ub978 \uc561\ud2f0\ube44\ud2f0\uc758 \ud638\ucd9c\ub85c \uce74\uba54\ub77c \ub9ac\uc18c\uc2a4\uc640, \ud14d\uc2a4\uccd0\ubdf0\ub4e4\uc774 \uc7a0\uc2dc \ube44\ud65c\uc131\ud654 \ub418\uc5c8\ub2e4\uac00 \ub2e4\uc2dc \uc7ac\uac8c \ub418\ub294\uacbd\uc6b0\uc5d0\ub294 if\ubb38\uc548\uc758 openCamera()\ub97c \ubc14\ub85c \ud638\ucd9c\ud558\uac8c \ub429\ub2c8\ub2e4.\u00a0<\/p>\n<pre class=\"lang:java decode:true\">private final TextureView.SurfaceTextureListener mSurfaceTextureListener\r\n        = new TextureView.SurfaceTextureListener() {\r\n...\r\n    @Override\r\n    public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {\r\n        openCamera(width, height);\r\n    }\r\n...\r\n};<\/pre>\n<p>\ucc98\uc74c \uc561\ud2f0\ube44\ud2f0\uac00 \uc2e4\ud589\ub418\uc5c8\ub2e4 \uac00\uc815\ud558\uba74, \ub2e4\uc74c\uacfc \uac19\uc774 TextureView\uac00 \ucd08\uae30\ud654\uac00 \uc644\ub8cc\ub418\uace0 \ud654\uba74\uc5d0 \ud14d\uc2a4\uccd0\ub97c \uadf8\ub9b4\uc900\ube44\uac00 \ub418\uc5c8\uc744\ub54c onSurfaceTextureAvailable()\uc744 \ud638\ucd9c\ud558\uac8c \ub429\ub2c8\ub2e4.\u00a0<\/p>\n<pre class=\"lang:java decode:true\">private void openCamera(int width, int height) {\r\n    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)\r\n            != PackageManager.PERMISSION_GRANTED) {\r\n        requestCameraPermission();\r\n        return;\r\n    }\r\n    setUpCameraOutputs(width, height);\r\n    configureTransform(width, height);\r\n    Activity activity = getActivity();\r\n    CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);\r\n    try {\r\n        if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {\r\n            throw new RuntimeException(\"Time out waiting to lock camera opening.\");\r\n        }\r\n        manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);\r\n    } catch (CameraAccessException e) {\r\n        e.printStackTrace();\r\n    } catch (InterruptedException e) {\r\n        throw new RuntimeException(\"Interrupted while trying to lock camera opening.\", e);\r\n    }\r\n}<\/pre>\n<p>openCamera()\ub97c \uc0b4\ud3b4\ubcf4\uba74 TextureView\uc758 \uc0ac\uc774\uc988\ub97c \uc785\ub825\ubc1b\uc544 \uc5ec\ub7ec\uac00\uc9c0\uc791\uc5c5\ub4e4\uc744 \uc218\ud589\ud558\uac8c \ub429\ub2c8\ub2e4.\u00a0<br \/>\n\uccab\ubc88\uc9f8\ub85c \uce74\uba54\ub77c \ub7f0\ud0c0\uc784 \ud37c\ubbf8\uc158\uc774 \uc788\ub294\uc9c0 \ud655\uc778\ud558\uac8c \ub418\uace0, \ud37c\ubbf8\uc158\uc744 \uc5bb\uc5c8\ub2e4\uba74 setUpCameraOutputs()\ub97c \uc218\ud589\ud558\uac8c \ub429\ub2c8\ub2e4.\u00a0<\/p>\n<p><strong>setUpCameraOutputs()\uac00 \ud558\ub294\uc77c<\/strong><\/p>\n<ul>\n<li>\ud6c4\uba74 \uce74\uba54\ub77c \uc120\ud0dd<\/li>\n<li>\ucea1\uccd0\ub41c \uc0ac\uc9c4(\uc774\ubbf8\uc9c0\ub9ac\ub354)\uc758 \ud574\uc0c1\ub3c4, \ud3ec\ub9f7 \uc120\ud0dd<\/li>\n<li>\uc774\ubbf8\uc9c0\uc758 \ubc29\ud5a5<\/li>\n<li>\uc801\ud569\ud55c \ud504\ub9ac\ubdf0 \uc0ac\uc774\uc988 \uc120\ud0dd<\/li>\n<li>\ub4e4\uc5b4\uc624\ub294 \uc601\uc0c1\uc758 \ube44\uc728\uc5d0 \ub9de\ucdb0 TextureView\uc758 \ube44\uc728 \ubcc0\uacbd(\uc774 \ubd80\ubd84\uc740 \uc608\uc81c\uc5d0 \ud3ec\ud568\ub41c AutoFitTextureView \ucee4\uc2a4\ud140 \ubdf0\uc785\ub2c8\ub2e4)<\/li>\n<li>\ud50c\ub798\uc2dc \uc9c0\uc6d0 \uc5ec\ubd80<\/li>\n<\/ul>\n<p><strong>configureTransform()\uac00 \ud558\ub294\uc77c<\/strong><\/p>\n<ul>\n<li>\uc2a4\ud06c\ub9b0\uacfc \uce74\uba54\ub77c\uc758 \uc601\uc0c1\uc758 \ubc29\ud5a5\uc744 \ub9de\ucd94\uae30 \uc704\ud574 View\ub97c \ub9e4\ud2b8\ub9ad\uc2a4 \uc5f0\uc0b0\uc73c\ub85c \ud68c\uc804\uc2dc\ud0b4<\/li>\n<\/ul>\n<p>Camera\ub97c \uc5f4\uae30\uc704\ud55c \uc120\uc791\uc5c5\ub4e4\uc774 \ub05d\ub0ac\ub2e4\uba74\u00a0CameraManager\ub97c \ud1b5\ud574 openCamera(\uce74\uba54\ub77cID, CameraDevice.StateCallback, \ud578\ub4e4\ub7ec)\ub97c \ud638\ucd9c\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {\r\n...\r\n    @Override\r\n    public void onOpened(@NonNull CameraDevice cameraDevice) {\r\n        mCameraOpenCloseLock.release();\r\n        mCameraDevice = cameraDevice;\r\n        createCameraPreviewSession();\r\n    }\r\n...\r\n};<\/pre>\n<p>\uce74\uba54\ub77c\uac00 \uc5f4\ub9ac\uace0 \ub098\uba74 onOpend(cameraDevice)\uac00 \ud638\ucd9c\ub429\ub2c8\ub2e4. \uce74\uba54\ub77c\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \uc5f4\ub838\uc73c\ubbc0\ub85c \uc774\uc81c \ud504\ub9ac\ubdf0\uc138\uc158\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\ub3c4\ub85d \ud558\uaca0\uc2b5\ub2c8\ub2e4.\u00a0<\/p>\n<pre class=\"lang:java decode:true\">private void createCameraPreviewSession() {\r\n    try {\r\n        SurfaceTexture texture = mTextureView.getSurfaceTexture();\r\n        assert texture != null;\r\n        texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());\r\n        \r\n        Surface surface = new Surface(texture);\r\n        \r\n        mPreviewRequestBuilder\r\n                = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);\r\n        mPreviewRequestBuilder.addTarget(surface);\r\n        \/\/ Here, we create a CameraCaptureSession for camera preview.\r\n        mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),\r\n                new CameraCaptureSession.StateCallback() {\r\n                    @Override\r\n                    public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {\r\n                        \/\/ The camera is already closed\r\n                        if (null == mCameraDevice) {\r\n                            return;\r\n                        }\r\n                        \/\/ When the session is ready, we start displaying the preview.\r\n                        mCaptureSession = cameraCaptureSession;\r\n                        try {\r\n                            \/\/ Auto focus should be continuous for camera preview.\r\n                            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,\r\n                                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);\r\n                            \/\/ Flash is automatically enabled when necessary.\r\n                            setAutoFlash(mPreviewRequestBuilder);\r\n                            \/\/ Finally, we start displaying the camera preview.\r\n                            mPreviewRequest = mPreviewRequestBuilder.build();\r\n                            mCaptureSession.setRepeatingRequest(mPreviewRequest,\r\n                                    mCaptureCallback, mBackgroundHandler);\r\n                        } catch (CameraAccessException e) {\r\n                            e.printStackTrace();\r\n                        }\r\n                    }\r\n                    @Override\r\n                    public void onConfigureFailed(\r\n                            @NonNull CameraCaptureSession cameraCaptureSession) {\r\n                        showToast(\"Failed\");\r\n                    }\r\n                }, null\r\n        );\r\n    } catch (CameraAccessException e) {\r\n        e.printStackTrace();\r\n    }\r\n}<\/pre>\n<p>createCameraPreviewSession()\uc5d0\uc11c \ud504\ub9ac\ubdf0 \uc138\uc158 \uc0dd\uc131 \ud558\ub294 \uc21c\uc11c<\/p>\n<ol>\n<li>Preview \uc138\uc158\uc744 \ub9cc\ub4e4\uae30 \uc704\ud574\uc11c TextureView\uac00 \uac00\uc9c0\uace0 \uc788\ub294 SurfaceTexture\ub97c \uac00\uc838\uc635\ub2c8\ub2e4. SurfaceTexture\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \uc774\uc804 <a href=\"https:\/\/www.charlezz.com\/?p=1024\">\ud3ec\uc2a4\ud2b8<\/a>\ub85c \ub300\uccb4\ud569\ub2c8\ub2e4.<\/li>\n<li>SurfaceTexture\uc5d0 setUpCameraOutputs()\uc5d0\uc11c \uacc4\uc0b0\ud55c \uae30\ubcf8 \ubc84\ud37c \uc0ac\uc774\uc988\ub97c \uc124\uc815\ud569\ub2c8\ub2e4.<\/li>\n<li>SufaceTexture\ub97c \uc774\uc6a9\ud558\uc5ec Surface\ub97c \ub9cc\ub4ed\ub2c8\ub2e4.<\/li>\n<li>CaptureRequest.Builder\uc5d0 surface\ub97c \ud0c0\uac9f\uc73c\ub85c \uc9c0\uc815\ud569\ub2c8\ub2e4.<\/li>\n<li>\uc9c0\uc815\ub41c \ud0c0\uac9f\uc740 \uc2e4\uc81c \uce74\uba54\ub77c \ud504\ub808\uc784 \ubc84\ud37c\ub97c \ubc1b\uc544 \ucc98\ub9ac\ud558\uac8c \ub429\ub2c8\ub2e4. \uc544\uc9c1 CaptureRequest\ub97c \uc0ac\uc6a9\ud560\uc21c \uc5c6\uc2b5\ub2c8\ub2e4. \ucea1\uccd0\uc138\uc158\uc774 \uba3c\uc800 \ub9cc\ub4e4\uc5b4\uc838\uc57c \ud569\ub2c8\ub2e4.<\/li>\n<li>CameraDevice.createCaptureSession()\uc744 \ud1b5\ud574 \uc138\uc158\uc744 \ub9cc\ub4ed\ub2c8\ub2e4.<\/li>\n<li>\ucea1\uccd0 \uc138\uc158\uc774 \ub9cc\ub4e4\uc5b4\uc84c\ub2e4\uba74 CameraCaptureSession.StateCallback\uc758 onConfigured()\uac00 \ud638\ucd9c \ub418\uac8c \ub429\ub2c8\ub2e4.<\/li>\n<li>onConfigured()\uc5d0\uc11c CaptureRequest.Builder\uc778\uc2a4\ud134\uc2a4\ub97c build()\ud558\uc5ec CaptureRequest\uac1d\uccb4\ub97c \ub9cc\ub4ed\ub2c8\ub2e4.<\/li>\n<li>\ubc18\ubcf5\uc801\uc73c\ub85c \uc774\ubbf8\uc9c0 \ubc84\ud37c\ub97c \uc5bb\uae30 \uc704\ud574 \ud504\ub9ac\ubdf0 \uc138\uc158\uc5d0\uc11c setRepeatingRequest()\ub97c \ud638\ucd9c\ud569\ub2c8\ub2e4. \uc774\ub807\uac8c \ud558\uba74 TextureView\uc5d0 \uce74\uba54\ub77c \uc601\uc0c1\uc774 \ub098\uc624\ub294\uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/li>\n<\/ol>\n<p>\uce74\uba54\ub77c \uc7a5\uce58\ub294 \uc2f1\uae00\ud1a4 \uc778\uc2a4\ud134\uc2a4\uc774\ubbc0\ub85c \uc0ac\uc6a9\ud6c4 \ubc18\ub4dc\uc2dc \uc2dc\uc2a4\ud15c\uc5d0 \ubc18\ud658\ud558\uc5ec \ub2e4\ub978 \ud504\ub85c\uc138\uc2a4(\uc571)\uac00 \uc774\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">@Override\r\npublic void onPause() {\r\n    closeCamera();\r\n    stopBackgroundThread();\r\n    super.onPause();\r\n}<\/pre>\n<p>\uc0ac\uc9c4\uc744 \ucc0d\ub294 \ubd80\ubd84\uc758 \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">private void takePicture() {\r\n    lockFocus();\r\n}\r\n\r\nprivate void lockFocus() {\r\n    try {\r\n\r\n        mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,\r\n                CameraMetadata.CONTROL_AF_TRIGGER_START);\r\n        mState = STATE_WAITING_LOCK;\r\n        mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler)\r\n    } catch (CameraAccessException e) {\r\n        e.printStackTrace();\r\n    }\r\n}<\/pre>\n<p>\uce74\uba54\ub77c\uc5d0\uac8c \ucd08\uc810\uc744 \uc7a1\uc73c\ub77c\uace0 request\ub97c \ubcf4\ub0b4\uae30 \uc704\ud574 \ud574\ub2f9 \ud30c\ub77c\ubbf8\ud130\ub97c \uc124\uc815\ud574\uc90d\ub2c8\ub2e4. \uc900\ube44\ub41c \uc138\uc158\uc73c\ub85c\ubd80\ud130 capture()\uba54\uc18c\ub4dc\uc640 \ud568\uaed8 request\uc778\uc790\ub97c \ub123\uc5b4 \ud638\ucd9c\ud569\ub2c8\ub2e4. \ucd08\uc810\uc774 \uc7a1\ud614\ub2e4\uba74 mCaptureCallback\uc73c\ub85c\ubd80\ud130 captureStillPicture()\uc744 \ud638\ucd9c\ud558\uac8c \ub420\uac83\uc785\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">private void captureStillPicture() {\r\n    try {\r\n        ...\r\n        final CaptureRequest.Builder captureBuilder =\r\n                mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);\r\n        captureBuilder.addTarget(mImageReader.getSurface());\r\n        ...\r\n        mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);\r\n    } catch (CameraAccessException e) {\r\n        e.printStackTrace();\r\n    }\r\n}<\/pre>\n<p>\ub610 \ub2e4\uc2dc CaptureSession\uc5d0 CaptureRequest\ub97c \ub123\uc5b4 \uc0ac\uc9c4\uc744 \ucea1\uccd0\ud558\ub294\ub370 \uc774\ub54c\uc758 \ucea1\uccd0\ud55c \uc774\ubbf8\uc9c0 \ubc84\ud37c\ub97c \ubc1b\uc744 Surface\ub294 \uc544\uae4c TextureView\uc758 Surface\uac00 \uc544\ub2cc ImageReader\uc758 Surface\uc785\ub2c8\ub2e4.<\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/?attachment_id=1127\" rel=\"attachment wp-att-1127\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2019-03-04-\u110b\u1169\u1112\u116e-9.16.52.png\" alt=\"\" width=\"252\" height=\"486\" class=\"aligncenter size-full wp-image-1127\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2019-03-04-\u110b\u1169\u1112\u116e-9.16.52.png 252w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2019\/03\/\u1109\u1173\u110f\u1173\u1105\u1175\u11ab\u1109\u1163\u11ba-2019-03-04-\u110b\u1169\u1112\u116e-9.16.52-156x300.png 156w\" sizes=\"(max-width: 252px) 100vw, 252px\" \/><\/a><\/p>\n<p>\uc5ec\uae30\uc11c \uc911\uc694\ud55c\uac83\uc740 \uc704\uc5d0\uc11c \uc54c\uc544\ubcf8 \uc6cc\ud06c\ud50c\ub85c\uc6b0\ub300\ub85c \ucd9c\ub825\ub418\ub294 \uc774\ubbf8\uc9c0 \ubc84\ud37c\uc758 \uc2a4\ud2b8\ub9bc\uc744 \ubc1b\uc544 \ucc98\ub9ac\ud560 \uc218 \uc788\ub294 \uac83\uc740 SurfaceTexture\uc640 ImageReader\ubfd0\ub9cc \uc544\ub2c8\ub77c, Surface\ub97c \uac00\uc9c0\uace0 \uc788\ub294 MediaCodec, MediaRecorder \ub4f1\ub3c4 \ubc84\ud37c\ub97c \ubc1b\uc744 \uc218 \uc788\ub2e4\ub294 \uc810\uc785\ub2c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; \uce74\uba54\ub77c Android\uc758 \uce74\uba54\ub77c HAL (Hardware Abstraction Layer)\uc740 Camera 2\uc758 \uc0c1\uc704 \uc218\uc900\uc758 \uce74\uba54\ub77c \ud504\ub808\uc784 \uc6cc\ud06c API\ub97c \uae30\ubcf8 \uce74\uba54\ub77c \ub4dc\ub77c\uc774\ubc84 \ubc0f \ud558\ub4dc\uc6e8\uc5b4\uc5d0 \uc5f0\uacb0\ud569\ub2c8\ub2e4. \uce74\uba54\ub77c \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc740 \uce74\uba54\ub77c \ud30c\uc774\ud504 \ub77c\uc778 \uad6c\uc131 \uc694\uc18c\uc5d0 \ub300\ud55c \uad6c\ud604\uc744 \ud3ec\ud568\ud558\ub294 \ubc18\uba74 \uce74\uba54\ub77c HAL\uc740 \uc774\ub7ec\ud55c \uad6c\uc131 \uc694\uc18c\uc758 \ubc84\uc804\uc744 \uad6c\ud604\ud558\ub294 \ub370 \uc0ac\uc6a9\ud560 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc81c\uacf5\ud569\ub2c8\ub2e4. \uad6c\uc870 \ub2e4\uc74c \uadf8\ub9bc\uacfc \ubaa9\ub85d\uc740 HAL [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[24],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/1118"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1118"}],"version-history":[{"count":7,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/1118\/revisions"}],"predecessor-version":[{"id":43930,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/1118\/revisions\/43930"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}