gpt4 book ai didi

android - 使用 cameraX 的 PreviewView 捕获叠加层

转载 作者:行者123 更新时间:2023-12-03 13:40:25 26 4
gpt4 key购买 nike

我正在尝试使用图像捕获中包含的叠加层来捕获图片。我能够将覆盖设置为 previewView使用 cameraView.overlay.add(binding.textView) .但是,当尝试使用 imageCapture 保存图像时,它没有保存。只有图片被保存而不是覆盖。如何使用 PreviewView 保存包含叠加层的图像相机 x。
请不要将此标记为重复。我研究了很多,大多数在线示例都使用旧的 camera不适用于相机 x 库的 api。任何帮助表示赞赏。提前致谢。
这是我的代码


<FrameLayout
android:id="@+id/camera_wrapper"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="@id/space1"
app:layout_constraintBottom_toBottomOf="@id/space">

<androidx.camera.view.PreviewView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hello world"
android:textSize="42sp"
android:textColor="@android:color/holo_green_dark"/>

</FrameLayout>

  private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService
private var preview: Preview? = null
private var lensFacing: Int = CameraSelector.LENS_FACING_FRONT
private var imageCapture: ImageCapture? = null
private var camera: Camera? = null
private var cameraProvider: ProcessCameraProvider? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
outputDirectory = getOutputDirectory()
cameraExecutor = Executors.newSingleThreadExecutor()
}

private fun setupCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())

cameraProviderFuture.addListener(
Runnable {
// Used to bind the lifecycle of cameras to the lifecycle owner
cameraProvider = cameraProviderFuture.get()

// Get screen metrics used to setup camera for full screen resolution
val metrics = DisplayMetrics().also { binding.cameraView.display.getRealMetrics(it) }
Timber.d("Screen metrics: ${metrics.widthPixels} x ${metrics.heightPixels}")

val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
Timber.d("Preview aspect ratio: $screenAspectRatio")

val rotation = binding.cameraView.display.rotation

// CameraProvider
val cameraProvider = cameraProvider
?: throw IllegalStateException("Camera initialization failed.")

// CameraSelector
val cameraSelector = CameraSelector.Builder().requireLensFacing(lensFacing).build()

// add text overlay *---------*
binding.cameraView.overlay.add(binding.textView)

// Preview
preview = Preview.Builder()
// We request aspect ratio but no resolution
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation
.setTargetRotation(rotation)
.build()

// ImageCapture
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
// We request aspect ratio but no resolution to match preview config, but letting
// CameraX optimize for whatever specific resolution best fits our use cases
.setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation, we will have to call this again if rotation changes
// during the lifecycle of this use case
.setTargetRotation(rotation)
.build()

// Must unbind the use-cases before rebinding them
cameraProvider.unbindAll()

try {
// A variable number of use-cases can be passed here -
// camera provides access to CameraControl & CameraInfo
camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture)
// Attach the viewfinder's surface provider to preview use case
preview?.setSurfaceProvider(binding.cameraView.surfaceProvider)
} catch (exc: Exception) {
Toast.makeText(requireContext(), "Something went wrong. Please try again.", Toast.LENGTH_SHORT).show()
findNavController().navigateUp()
}
},
ContextCompat.getMainExecutor(requireContext())
)
}

private fun takePhoto() {
imageCapture?.let { imageCapture ->

// Create output file to hold the image
val photoFile = createFile(outputDirectory, FILENAME, PHOTO_EXTENSION)

// Setup image capture metadata
val metadata = ImageCapture.Metadata().apply {

// Mirror image when using the front camera
isReversedHorizontal = lensFacing == CameraSelector.LENS_FACING_FRONT
}

// Create output options object which contains file + metadata
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile)
.setMetadata(metadata)
.build()

// Setup image capture listener which is triggered after photo has been taken
imageCapture.takePicture(outputOptions, cameraExecutor, object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Timber.e(exc, "Photo capture failed: ${exc.message}")
}

override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val savedUri = output.savedUri ?: Uri.fromFile(photoFile)
Timber.d("Photo capture succeeded: $savedUri")

// Implicit broadcasts will be ignored for devices running API level >= 24
// so if you only target API level 24+ you can remove this statement
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
requireActivity()
.sendBroadcast(Intent(android.hardware.Camera.ACTION_NEW_PICTURE, savedUri))
}


// If the folder selected is an external media directory, this is
// unnecessary but otherwise other apps will not be able to access our
// images unless we scan them using [MediaScannerConnection]
val mimeType = MimeTypeMap.getSingleton()
.getMimeTypeFromExtension(savedUri.toFile().extension)
MediaScannerConnection.scanFile(
context,
arrayOf(savedUri.toFile().absolutePath),
arrayOf(mimeType)
) { _, uri ->
Timber.d("Image capture scanned into media store: $uri")
}
}
})
}

}


最佳答案

您必须自己将文本覆盖在图像上。我建议使用 takePicture(Executor, …)将 Jpeg 放入内存中;然后,使用其中一个库(不是 Android 框架的一部分,也不是 Jetpack 的一部分)覆盖您的文本,并将结果保存在文件中。
如果您可以在图像质量上妥协,您可以在位图 Canvas 上绘制 Jpeg,然后在顶部绘制文本。

关于android - 使用 cameraX 的 PreviewView 捕获叠加层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64903838/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com