解决相机库CameraView多滤镜拍照错乱的BUG (一) : 复现BUG

1. 前言

这段时间,在使用 natario1/CameraView 来实现带滤镜的预览拍照录像功能。

由于CameraView封装的比较到位,在项目前期,的确为我们节省了不少时间。

但随着项目持续深入,对于CameraView的使用进入深水区,逐渐出现满足不了我们需求的情况。
Github中的issues中,有些BUG作者一直没有修复。

那要怎么办呢 ? 项目迫切地需要实现相关功能,只能自己硬着头皮去看它的源码,去解决这些问题。

而这篇文章是其中关于CameraView在使用多滤镜MultiFilter的时候哦度会遇到拍照错乱的BUG

以下源码解析基于CameraView 2.7.2

kotlin 复制代码
implementation("com.otaliastudios:cameraview:2.7.2")

为了在博客上更好的展示,本文贴出的代码进行了部分精简

2. 复现BUG

2.1 添加权限

AndroidManifest.xml中添加权限

xml 复制代码
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

别忘了申请权限

kotlin 复制代码
ActivityCompat.requestPermissions(
    this,
    arrayOf(
        android.Manifest.permission.CAMERA,
        android.Manifest.permission.RECORD_AUDIO,
        android.Manifest.permission.WRITE_EXTERNAL_STORAGE
    ),
    1
)

2.2 在XML中添加布局

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MyMainActivity">

    <com.otaliastudios.cameraview.CameraView
        android:id="@+id/camera_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cameraFacing="back"
        app:cameraEngine="camera2"
        app:cameraExperimental="true"
        app:cameraMode="picture" />

    <Button
        android:id="@+id/btn_take_picture"
        android:layout_gravity="right|bottom"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:text="拍照" />

</FrameLayout>

2.3 实现Activity

Activity中添加如下代码

kotlin 复制代码
class CameraActivity : AppCompatActivity() {
    private lateinit var binding: ActivityTest2Binding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityTest2Binding.inflate(layoutInflater)
        setContentView(binding.root)

        //TODO 申请权限,这里略过,详见上文

        binding.btnTakePicture.setOnClickListener {
            //调用带滤镜拍照
            binding.cameraView.takePictureSnapshot()
        }

        binding.cameraView.addCameraListener(object : CameraListener() {
            override fun onPictureTaken(result: PictureResult) {
                super.onPictureTaken(result)
                //拍照回调
                val res = BitmapFactory.decodeByteArray(result.data, 0, result.data.size)
                res?.also {
                    val file = getNewImageFile()
                    ImageUtils.save(it, file, Bitmap.CompressFormat.JPEG)
                }
            }
        })
        //初始化CameraView
        binding.cameraView.setLifecycleOwner(this)
        val multiFilter = MultiFilter()
        val crossProcess = Filters.CROSS_PROCESS.newInstance()
        multiFilter.addFilter(crossProcess)
        //设置滤镜
        binding.cameraView.filter = multiFilter
    }
}

2.4 运行项目

接着运行项目,预览时正常的,点击拍照,可以发现,带滤镜拍出来的图片是正常的。

2.5 使用两个滤镜

然后我们改成使用两个滤镜

kotlin 复制代码
//初始化CameraView
binding.cameraView.setLifecycleOwner(this)
val multiFilter = MultiFilter()
val crossProcess = Filters.CROSS_PROCESS.newInstance()
multiFilter.addFilter(crossProcess)
val vignette = Filters.VIGNETTE.newInstance()
multiFilter.addFilter(vignette)
//设置滤镜
binding.cameraView.filter = multiFilter

默认情况下,CameraView会使用摄像头支持的最大像素进行拍照,我这个手机CameraView最终选用的摄像头分辨率是3072x4096,而我的手机屏幕分辨率是1080*2412(也就是CameraView的分辨率),预览时候是正常的,拍出来的照片居然放大了 ?

2.6 使用1080P

我们再将CameraView拍照的分辨率强制指定为1920*1080,而我的手机屏幕分辨率是1080*2412,预览也是正常的,这个时候拍出来的照片却是比实际尺寸缩小的。

3. BUG小结

至此,我们可以总结这个BUG,是跟CameraView的尺寸和摄像头选取的分辨率匹配有关。

  • 使用单个滤镜
    • 一切正常
  • 使用多个滤镜,预览正常,但是
    • 手机选用的摄像头分辨率比CameraView分辨率高 : 照片得到的画面会放大
    • 手机选用的摄像头分辨率比CameraView分辨率低 : 拍照得到的画面会缩小,会有黑边

那这到底是为什么呢 ? 又该怎么解决呢 ?

我们在下一篇文章中做详细分析 : 解决相机库CameraView多滤镜拍照错乱的BUG (二) : 解决BUG

4. 其他

4.1 CameraView源码解析系列

Android 相机库CameraView源码解析 (一) : 预览-CSDN博客
Android 相机库CameraView源码解析 (二) : 拍照-CSDN博客
Android 相机库CameraView源码解析 (三) : 滤镜相关类说明-CSDN博客
Android 相机库CameraView源码解析 (四) : 带滤镜预览-CSDN博客
Android 相机库CameraView源码解析 (五) : 带滤镜拍照-CSDN博客
Android 相机库CameraView源码解析 (六) : 保存滤镜效果-CSDN博客

相关推荐
拭心2 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王4 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡4 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道5 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库6 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道6 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe6 小时前
Android Hook - 动态加载so库
android
居居飒7 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He10 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗10 小时前
Android笔试面试题AI答之Android基础(1)
android