In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces Android CameraX how to combine LibYUV and GPUImage custom camera filter, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let Xiaobian take you to understand.
The contents of this article:
Realize the effect
Implement step 1. Introduce dependency libraries the dependency libraries I introduce here are CameraX, GPUImage (filter library), Utilcodex (a useful tool class)
/ / CameraX core library using camera2 implementation implementation "androidx.camera:camera-camera2:1.0.1" / / CameraX Lifecycle Library implementation "androidx.camera:camera-lifecycle:1.0.1" / / CameraX View class implementation "androidx.camera:camera-view:1.0.0-alpha27" implementation'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1' implementation' com.blankj:utilcodex:1.30.6'2. Introducing libyuv here I use the libyuv in this case (https://github.com/theeasiestway/android-yuv-utils), as follows
3. The layout code for writing CameraX preview code is as follows
The preview codes for enabling the camera in Activity are as follows, which are basically the case codes provided officially by Google.
Class MainActivity: AppCompatActivity () {private lateinit var cameraExecutor: ExecutorService override fun onCreate (savedInstanceState: Bundle?) {super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) cameraExecutor = Executors.newSingleThreadExecutor () / / Request camera permissions if (allPermissionsGranted ()) {startCamera ()} else {ActivityCompat.requestPermissions (this, REQUIRED_PERMISSIONS REQUEST_CODE_PERMISSIONS)} private fun allPermissionsGranted () = REQUIRED_PERMISSIONS.all {ContextCompat.checkSelfPermission (baseContext, it) = = PackageManager.PERMISSION_GRANTED} override fun onRequestPermissionsResult (requestCode: Int, permissions: Array, grantResults: IntArray) {super.onRequestPermissionsResult (requestCode, permissions) GrantResults) if (requestCode = = REQUEST_CODE_PERMISSIONS) {if (allPermissionsGranted ()) {startCamera ()} else {Toast.makeText (this, "Permissions not granted by the user." Toast.LENGTH_SHORT) .show () finish ()}} private fun startCamera () {val cameraProviderFuture = ProcessCameraProvider.getInstance (this) cameraProviderFuture.addListener (Runnable {val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get () val preview = Preview.Builder () .build () .also {it.setSurfaceProvider (viewFinder.surfaceProvider)} val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA try {cameraProvider.unbindAll () cameraProvider.bindToLifecycle (this) CameraSelector, preview)} catch (exc: Exception) {Log.e (TAG, "Use case binding failed", exc)}} ContextCompat.getMainExecutor (this)} override fun onDestroy () {super.onDestroy () cameraExecutor.shutdown ()} companion object {private const val TAG = "CameraXBasic" private const val REQUEST_CODE_PERMISSIONS = 10 privateval REQUIRED_PERMISSIONS = arrayOf (Manifest.permission.CAMERA)}} camera preview can be realized here
4. To increase the camera data callback, if we want to increase the filter effect, we must manipulate the camera data. Here, we obtain the modifiable data by getting the camera data callback.
Val imageAnalyzer = ImageAnalysis.Builder () / / sets the ratio of callback data to 16:9. SetTargetAspectRatio (AspectRatio.RATIO_16_9) .build () .also {it.setAnalyzer (cameraExecutor,this@MainActivity)} here we also need to bind
In addition, we also need to implement the ImageAnalysis.Analyzer interface in Activity. The data acquisition is obtained in the callback method of this interface, as shown below, where ImageProxy contains image data.
Override fun analyze (image: ImageProxy) {} 5. To process the callback data, we process the image and add a filter in the camera data callback method, of course, before we need to create a GPUImage object and set the filter type
Private var bitmap:Bitmap? = nullprivate var gpuImage:GPUImage? = null// creates a GPUImage object and sets the filter type Here I use the sketch filter private fun initFilter () {gpuImage = GPUImage (this) gpuImageroom.setFilter (GPUImageSketchFilter ())} @ SuppressLint ("UnsafeOptInUsageError") override fun analyze (image: ImageProxy) {/ / convert the YUV data of Android into libYuv data var yuvFrame = yuvUtils.convertToI420 (image.imageimages!) / / A pair of images are rotated (due to callback cameras) The data is horizontal and therefore needs to be rotated 90 degrees) yuvFrame = yuvUtils.rotate (yuvFrame 90) / / create Bitmap bitmap = Bitmap.createBitmap (yuvFrame.width, yuvFrame.height, Bitmap.Config.ARGB_8888) / / convert the image to Argb format and fill the yuvUtils.yuv420ToArgb on the Bitmap (yuvFrame) based on the image size ) / / add a filter to the image using GpuImage bitmap = gpuImageFilterApplied (bitmap) / / since this is not a UI thread, you need to update UI img.post {img.setImageBitmap (bitmap) / / close ImageProxy in UI thread. Will call back the next data image.close ()}} 6. Take pictures. Here we add a button to take pictures.
Then we add the logic of taking pictures to the Activity, which is actually saving the Bitmap to the SD card. Here we use the Utilcodex tool introduced earlier. When we click the button, the isTakePhoto changes to true, and then the image is saved in the callback of the camera.
Bt_takepicture.setOnClickListener {isTakePhoto = true} and we add variable control so that callback data is not processed when taking pictures.
@ SuppressLint ("UnsafeOptInUsageError") override fun analyze (image: ImageProxy) {if (! isTakePhoto) {/ / convert the YUV data of Android to the data of libYuv var yuvFrame = yuvUtils.convertToI420 (image.imagerotation!) / A pair of images are rotated (90 degrees because the callback camera data is horizontal) yuvFrame = yuvUtils.rotate (yuvFrame 90) / / create Bitmap bitmap = Bitmap.createBitmap (yuvFrame.width, yuvFrame.height, Bitmap.Config.ARGB_8888) / / convert the image to Argb format and fill the yuvUtils.yuv420ToArgb on the Bitmap (yuvFrame) based on the image size ) / / use GpuImage to add a filter to the image bitmap = gpuImageFilterApplication.getBitmapWithFilterApplication (bitmap) / / since this is not a UI thread, you need to update UI img.post {img.setImageBitmap (bitmap) if (isTakePhoto) {takePhoto () in UI thread. } / / close ImageProxy The next data image.close ()}} else {image.close ()} / * Photo * / private fun takePhoto () {Thread {val filePath = File (getExternalFilesDir (Environment.DIRECTORY_DOWNLOADS)) will be called back. "${System.currentTimeMillis ()} save.jpg") ImageUtils.save (bitmap,filePath.absolutePath,Bitmap.CompressFormat.PNG) ToastUtils.showShort ("successful shooting") isTakePhoto = false} .start ()} effect is as follows
The saved pictures are in the following directory
The saved picture is as follows
Thank you for reading this article carefully. I hope the article "how to combine Android CameraX with LibYUV and GPUImage custom camera filters" shared by the editor will be helpful to you. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.