这段时间,在使用 natario1/CameraView 来实现带滤镜的预览
、拍照
、录像
功能。
由于CameraView
封装的比较到位,在项目前期,的确为我们节省了不少时间。
但随着项目持续深入,对于CameraView
的使用进入深水区,逐渐出现满足不了我们需求的情况。
Github
中的issues
中,有些BUG
作者一直没有修复。
那要怎么办呢 ? 项目迫切地需要实现相关功能,只能自己硬着头皮去看它的源码,去解决这些问题。
而这篇文章是其中关于CameraView
在使用多滤镜MultiFilter
的时候哦度会遇到拍照错乱的BUG
。
以下源码解析基于CameraView 2.7.2
implementation("com.otaliastudios:cameraview:2.7.2")
为了在博客上更好的展示,本文贴出的代码进行了部分精简
在AndroidManifest.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" />
别忘了申请权限
ActivityCompat.requestPermissions(
this,
arrayOf(
android.Manifest.permission.CAMERA,
android.Manifest.permission.RECORD_AUDIO,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
),
1
)
<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>
在Activity
中添加如下代码
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
}
}
接着运行项目,预览时正常的,点击拍照,可以发现,带滤镜拍出来的图片是正常的。
然后我们改成使用两个滤镜
//初始化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
的分辨率),预览时候是正常的,拍出来的照片居然放大了 ?
我们再将CameraView
拍照的分辨率强制指定为1920*1080
,而我的手机屏幕分辨率是1080*2412
,预览也是正常的,这个时候拍出来的照片却是比实际尺寸缩小的。
至此,我们可以总结这个BUG
,是跟CameraView
的尺寸和摄像头选取的分辨率匹配有关。
CameraView
分辨率高 : 照片得到的画面会放大CameraView
分辨率低 : 拍照得到的画面会缩小,会有黑边那这到底是为什么呢 ? 又该怎么解决呢 ?
我们在下一篇文章中做详细分析 : 解决相机库CameraView多滤镜拍照错乱的BUG (二) : 解决BUG
Android 相机库CameraView源码解析 (一) : 预览-CSDN博客
Android 相机库CameraView源码解析 (二) : 拍照-CSDN博客
Android 相机库CameraView源码解析 (三) : 滤镜相关类说明-CSDN博客
Android 相机库CameraView源码解析 (四) : 带滤镜预览-CSDN博客
Android 相机库CameraView源码解析 (五) : 带滤镜拍照-CSDN博客
Android 相机库CameraView源码解析 (六) : 保存滤镜效果-CSDN博客