R R*_*ara 5 kotlin android-camerax
我的自定义 CameraX 流程如下:
问题是何时running all the process (in step 3)有 adelayed 2 seconds并且相机预览静止live(not freeze或lock)。怎么做camera preview freeze or lock when running the process?
这是我在 Camera X 中运行相机预览的代码:
class CameraFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_camera, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewFinder.post { setupCamera() }
}
private fun setupCamera() {
CameraX.unbindAll()
CameraX.bindToLifecycle(
this,
buildPreviewUseCase(),
buildImageCaptureUseCase()
)
}
private fun buildPreviewUseCase(): Preview {
val preview = Preview(
UseCaseConfigBuilder.buildPreviewConfig(
viewFinder.display
)
)
preview.setOnPreviewOutputUpdateListener { previewOutput ->
updateViewFinderWithPreview(previewOutput)
correctPreviewOutputForDisplay(previewOutput.textureSize)
}
return preview
}
private fun buildImageCaptureUseCase(): ImageCapture {
val capture = ImageCapture(
UseCaseConfigBuilder.buildImageCaptureConfig(
viewFinder.display
)
)
cameraCaptureImageButton.setOnClickListener {
capture.takePicture(
FileCreator.createTempFile(JPEG_FORMAT),
Executors.newSingleThreadExecutor(),
object : ImageCapture.OnImageSavedListener {
override fun onImageSaved(file: File) {
// I want make a freeze camera preview when execute this before launch *launchGalleryFragment(path)*
val bitmap = BitmapFactory.decodeFile(file.absolutePath)
val rotatedBitmap = bitmap.rotate(90)
val croppedImage = cropImage(rotatedBitmap, viewFinder, rectangle)
val path = saveImage(croppedImage)
requireActivity().runOnUiThread {
launchGalleryFragment(path)
}
}
override fun onError(
imageCaptureError: ImageCapture.ImageCaptureError,
message: String,
cause: Throwable?
) {
Toast.makeText(requireContext(), "Error: $message", Toast.LENGTH_LONG)
.show()
Log.e("CameraFragment", "Capture error $imageCaptureError: $message", cause)
}
})
}
return capture
}
private fun launchGalleryFragment(path: String) {
val action = CameraFragmentDirections.actionLaunchGalleryFragment(path)
findNavController().navigate(action)
}
}
Run Code Online (Sandbox Code Playgroud)
也许您可以尝试解除预览用例的绑定:
版本1.0.0-alpha06:CameraX.unbind(preview);
版本 > 1.0.0-alpha07:cameraProvider.unbind(preview);
在您的情况下,您需要将预览用例保存到变量中,然后取消绑定:
// Declare the preview use case variable (as in the CameraXBasic example)
private var preview: Preview? = null
Run Code Online (Sandbox Code Playgroud)
然后实例化变量(就像你所做的那样):
private fun buildPreviewUseCase(): Preview {
preview = Preview(
UseCaseConfigBuilder.buildPreviewConfig(
viewFinder.display
)
)
preview.setOnPreviewOutputUpdateListener { previewOutput ->
updateViewFinderWithPreview(previewOutput)
correctPreviewOutputForDisplay(previewOutput.textureSize)
}
return preview
}
Run Code Online (Sandbox Code Playgroud)
然后,当您想要冻结预览时,只需取消绑定用例即可:
CameraX.unbind(preview);
Run Code Online (Sandbox Code Playgroud)
编辑 正如 @Billda 在这篇文章中所说:CameraX - 取消绑定预览用例时崩溃:
要冻结预览,您不应取消预览用例的绑定。将来可能会有 API,但目前推荐的方法是存储来自 ImageAnalysis 的最新帧并将其放置到与预览重叠的 ImageView 中。
因此,我决定更新我的答案,提供另一个使用 ImageAnalysis 实现分析器的解决方案(1.0.0-beta02)。
1- 创建 FreezeAnalyzer 类:
class FreezeAnalyzer(private val callback: FreezeCallback) : ImageAnalysis.Analyzer {
private var flag = false
override fun analyze(image: ImageProxy) {
if(flag){
flag = false
val bitmap = toBitmap(image)
callback.onLastFrameCaptured(bitmap)
}
image.close()
}
fun freeze(){
flag = true
}
private fun toBitmap(image: ImageProxy): Bitmap {
// Convert the imageProxy to Bitmap
// ref /sf/ask/3974107721/
// ISSUE, on my android 7 when converting the imageProxy to Bitmap I have a problem with the colors...
var bitmap = ...
// Rotate the bitmap
val rotationDegrees = image.imageInfo.rotationDegrees.toFloat()
if (rotationDegrees != 0f) {
val matrix = Matrix()
matrix.postRotate(rotationDegrees)
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
return bitmap
}
}
Run Code Online (Sandbox Code Playgroud)
2-XML
<androidx.camera.view.PreviewView
android:id="@+id/preview_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/image_view"
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Run Code Online (Sandbox Code Playgroud)
3-初始化图像分析器
val resolutionSize = Size(preview_view.width, preview_view.height)
// Set up analyser
imageAnalysis = ImageAnalysis.Builder().apply {
setTargetResolution(resolutionSize)
setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
}.build()
val analyzer = FreezeAnalyzer(object : FreezeCallback {
override fun onLastFrameCaptured(bitmap: Bitmap) {
runOnUiThread {
preview_view.visibility = View.INVISIBLE
image_view.visibility = View.VISIBLE
image_view.setImageBitmap(bitmap)
}
}
})
imageAnalysis.setAnalyzer(executor, analyzer)
Run Code Online (Sandbox Code Playgroud)
4- 绑定 imageAnalysis 用例
try {
val camera = cameraProvider.bindToLifecycle(
this,
cameraSelector,
preview,
imageAnalysis,
imageCapture
)
preview.setSurfaceProvider(preview_view.createSurfaceProvider(camera.cameraInfo))
}
Run Code Online (Sandbox Code Playgroud)
5-拍摄照片
btn_capture.setOnClickListener {
file = File(externalMediaDirs.first(), "${System.currentTimeMillis()}.jpg")
val outputFileOptions: ImageCapture.OutputFileOptions =
ImageCapture.OutputFileOptions.Builder(file!!).build()
analyzer.freeze()
imageCapture.takePicture(outputFileOptions, executor, onImageSavedCallback)
}
Run Code Online (Sandbox Code Playgroud)
6-释放
btn_release.setOnClickListener {
preview_view.visibility = View.VISIBLE
image_view.visibility = View.INVISIBLE
}
Run Code Online (Sandbox Code Playgroud)
我希望它有所帮助,我不是专家,所以如果您有一些改进,欢迎您!
| 归档时间: |
|
| 查看次数: |
6343 次 |
| 最近记录: |