Commit b3568d25 authored by wanglei's avatar wanglei

...

parent 865913ca
Pipeline #1426 failed with stages
......@@ -6,15 +6,18 @@ import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.Preview
import androidx.camera.core.ZoomState
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.view.PreviewView
import androidx.core.content.ContextCompat
import androidx.lifecycle.LiveData
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
class CameraUtils(
val activity: AppCompatActivity,
) {
......@@ -27,6 +30,9 @@ class CameraUtils(
private var cameraProvider: ProcessCameraProvider? = null
private var imageAnalyzer: ImageAnalysis? = null
var cameraReadyCallBack: (() -> Unit)? = null
init {
cameraExecutor = Executors.newSingleThreadExecutor()
}
......@@ -97,6 +103,7 @@ class CameraUtils(
} catch (exc: Exception) {
exc.printStackTrace()
}
cameraReadyCallBack?.invoke()
}
/**
......@@ -142,6 +149,62 @@ class CameraUtils(
return AspectRatio.RATIO_16_9
}
/**
* 打开闪光灯
*/
fun turnOnFlash() {
val cameraControl = camera?.cameraControl
cameraControl?.enableTorch(true)
}
/**
* 关闭闪光
*/
fun turnOffFlash() {
val cameraControl = camera?.cameraControl
cameraControl?.enableTorch(false)
}
/**
* 获取闪光状态
*/
fun getFlashState(): LiveData<Int>? {
return camera?.cameraInfo?.torchState
}
/**
* 是否支持变焦
*/
fun isZoomSupported(): Boolean {
val zoomState: ZoomState? = camera?.cameraInfo?.zoomState?.getValue()
if (zoomState != null && !java.lang.Float.isNaN(zoomState.minZoomRatio) && !java.lang.Float.isNaN(zoomState.maxZoomRatio)) {
// 相机支持变焦
return true
}
return false
}
/**
* 获取变焦范围
*/
fun getZoomRange(): Pair<Float, Float> {
val zoomState: ZoomState? = camera?.cameraInfo?.zoomState?.getValue()
if (zoomState != null) {
val minZoomRatio = zoomState.minZoomRatio
val maxZoomRatio = zoomState.maxZoomRatio
return Pair(minZoomRatio, maxZoomRatio)
}
return Pair(0f, 100f)
}
/**
* 设置变焦值
*/
fun setZoomRate(ratio: Float) {
val cameraControl = camera?.cameraControl
cameraControl?.setZoomRatio(ratio)
}
companion object {
private const val RATIO_4_3_VALUE = 4.0 / 3.0
private const val RATIO_16_9_VALUE = 16.0 / 9.0
......
......@@ -109,6 +109,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
naviFragment(this.id)
}
override fun onDestroy() {
super.onDestroy()
cameraUtils?.onDestroy()
}
override fun configSystemBar() {
super.configSystemBar()
immersionBar {
......
......@@ -2,9 +2,16 @@ package com.base.scanqr.ui.main
import android.Manifest
import android.content.pm.PackageManager
import android.hardware.camera2.CameraMetadata.FLASH_MODE_OFF
import android.view.View
import android.widget.SeekBar
import androidx.camera.core.ImageCapture.FLASH_MODE_ON
import com.base.scanqr.R
import com.base.scanqr.base.BaseFragment
import com.base.scanqr.databinding.FragmentScanBinding
import com.base.scanqr.qr.QRImageAnalyzer
import com.base.scanqr.utils.IntentUtils.intentSafPickImage
import com.base.scanqr.utils.LogEx
import com.base.scanqr.utils.PermissionUtils.checkCameraPermission
import com.gyf.immersionbar.ktx.immersionBar
import java.util.concurrent.atomic.AtomicBoolean
......@@ -13,6 +20,7 @@ import java.util.concurrent.atomic.AtomicBoolean
class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::inflate) {
private var zoomPair = Pair(0f, 100f)
override fun initView() {
super.initView()
}
......@@ -33,10 +41,42 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl
private fun initCamera() {
if (cameraInit.get()) return
val hasFlash = requireContext().packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)
if (!hasFlash) {
binding.flFlash.visibility = View.GONE
}
val qrImageAnalyzer = QRImageAnalyzer()
val activity = requireActivity() as MainActivity?
activity ?: return
activity.cameraUtils?.startBind(binding.previewView, qrImageAnalyzer)
activity.cameraUtils?.cameraReadyCallBack = {
//变焦
if (activity.cameraUtils?.isZoomSupported() != true) {
binding.llZoom.visibility = View.GONE
} else {
zoomPair = activity.cameraUtils?.getZoomRange() ?: Pair(0f, 100f)
LogEx.logDebug(TAG, "zoomPair=${zoomPair.first} ${zoomPair.second}")
binding.seekbar.max = ((zoomPair.second - zoomPair.first) * 10).toInt()
}
//闪光灯
activity.cameraUtils?.getFlashState()?.observe(this) { state ->
if (state == FLASH_MODE_OFF) {
binding.ivFlash.setImageResource(R.mipmap.shnadian_on)
binding.flFlash.setOnClickListener {
activity.cameraUtils?.turnOnFlash()
}
}
if (state == FLASH_MODE_ON) {
binding.ivFlash.setImageResource(R.mipmap.shandian_off)
binding.flFlash.setOnClickListener {
activity.cameraUtils?.turnOffFlash()
}
}
}
}
cameraInit.set(true)
}
......@@ -54,6 +94,42 @@ class ScanFragment : BaseFragment<FragmentScanBinding>(FragmentScanBinding::infl
override fun initListener() {
super.initListener()
binding.flImage.setOnClickListener {
val activity = requireActivity() as MainActivity?
val intent = intentSafPickImage()
activity?.launcher?.launch(intent)
}
binding.flFlash.setOnClickListener {
val activity = requireActivity() as MainActivity?
activity?.cameraUtils?.turnOnFlash()
}
binding.seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
val zoom = (zoomPair.first + seekBar.progress / 10f)
val activity = requireActivity() as MainActivity?
activity?.cameraUtils?.setZoomRate(zoom)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
}
override fun onStopTrackingTouch(seekBar: SeekBar) {
}
})
binding.flReduce.setOnClickListener {
val activity = requireActivity() as MainActivity?
activity?.cameraUtils?.setZoomRate(zoomPair.first)
binding.seekbar.progress = 0
}
binding.flAdd.setOnClickListener {
val activity = requireActivity() as MainActivity?
activity?.cameraUtils?.setZoomRate(zoomPair.second)
binding.seekbar.progress = binding.seekbar.max
}
}
......
......@@ -43,7 +43,7 @@ object IntentUtils {
return Intent()
}
fun intentShareText( text: String): Intent {
fun intentShareText(text: String): Intent {
val sendIntent = Intent()
sendIntent.action = Intent.ACTION_SEND
sendIntent.putExtra(Intent.EXTRA_TEXT, text) // 添加要分享的文本
......@@ -53,4 +53,12 @@ object IntentUtils {
val shareIntent = Intent.createChooser(sendIntent, null)
return shareIntent
}
fun intentSafPickImage(): Intent {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.setType("image/*")
return intent
}
}
\ No newline at end of file
......@@ -28,6 +28,7 @@
<LinearLayout
android:id="@+id/ll_zoom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
......@@ -39,7 +40,7 @@
app:layout_constraintStart_toStartOf="parent">
<FrameLayout
android:id="@+id/flAdd"
android:id="@+id/flReduce"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
......@@ -53,12 +54,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@mipmap/jia"
android:src="@mipmap/jian"
tools:ignore="ContentDescription" />
</FrameLayout>
<androidx.appcompat.widget.AppCompatSeekBar
android:id="@+id/seekbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
......@@ -70,7 +72,7 @@
tools:progress="50" />
<FrameLayout
android:id="@+id/flReduce"
android:id="@+id/flAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
......@@ -84,11 +86,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@mipmap/jian"
android:src="@mipmap/jia"
tools:ignore="ContentDescription" />
</FrameLayout>
</LinearLayout>
<LinearLayout
......@@ -103,6 +106,7 @@
app:layout_constraintStart_toStartOf="parent">
<FrameLayout
android:id="@+id/fl_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
......@@ -117,16 +121,18 @@
</FrameLayout>
<FrameLayout
android:id="@+id/fl_flash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="10dp">
<ImageView
android:id="@+id/iv_flash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@mipmap/shandian"
android:src="@mipmap/shandian_off"
tools:ignore="ContentDescription" />
</FrameLayout>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment