我想构建一个应用程序,用于同时使用双摄像头的两个摄像头拍照,并想问问是否有人知道新的 camerax api 是否允许我分别处理两个摄像头流。
因此,我想探索新的Google的Camera API- CameraX。我想做的是每秒从相机提要中获取一张图像,然后将其传递到接受位图的功能中,以进行机器学习。
我阅读了有关Camera XImage Analyzer 的文档:
图像分析用例为您的应用提供了CPU可访问的图像,以执行图像处理,计算机视觉或机器学习推断。该应用程序实现在每个框架上运行的Analyzer方法。
..这基本上是我需要的。因此,我实现了这个图像分析器,如下所示:
imageAnalysis.setAnalyzer { image: ImageProxy, _: Int ->
viewModel.onAnalyzeImage(image)
}
Run Code Online (Sandbox Code Playgroud)
我得到的是image: ImageProxy。我该如何将其转移ImageProxy到Bitmap?
我试图这样解决:
fun decodeBitmap(image: ImageProxy): Bitmap? {
val buffer = image.planes[0].buffer
val bytes = ByteArray(buffer.capacity()).also { buffer.get(it) }
return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}
Run Code Online (Sandbox Code Playgroud)
但是它返回null-因为decodeByteArray没有收到有效的(?)位图字节。有任何想法吗?
我正在使用 CameraX 并且很难将捕获的 ImageProxy 转换为位图。经过搜索和尝试,我制定了一个解决方案。后来我发现它不是最佳的,所以我改变了设计。这迫使我放弃工作时间。
由于我(或其他人)将来可能需要它,因此我决定将其作为问题发布在这里并发布和回答以供参考和审查。如果您有更好的答案,请随时添加更好的答案。
相关代码是:
class ImagePickerActivity : AppCompatActivity() {
private var width = 325
private var height = 205
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_image_picker)
view_finder.post { startCamera() }
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun startCamera() {
// Create configuration object for the viewfinder use case
val previewConfig = PreviewConfig.Builder().apply {
setTargetAspectRatio(Rational(1, 1))
//setTargetResolution(Size(width, height))
setLensFacing(CameraX.LensFacing.BACK)
setTargetAspectRatio(Rational(width, height))
}.build()
}
// Create configuration object for the image capture use case
val imageCaptureConfig = ImageCaptureConfig.Builder()
.apply {
setTargetAspectRatio(Rational(1, …Run Code Online (Sandbox Code Playgroud) 刚刚使用 CameraX 在 Android 中创建了一个相机预览,配置如下:
PreviewConfig previewConfig = new PreviewConfig.Builder()
.setLensFacing(CameraX.LensFacing.FRONT)
.setTargetResolution(new Size(720, 720))
.build();
Preview preview = new Preview(previewConfig);
Run Code Online (Sandbox Code Playgroud)
现在,问题是这样的目标分辨率可能不可用,在这种情况下,预览将选择与请求的分辨率接近的分辨率。我在这里问的是一种了解预览有效选择了哪种分辨率的方法。
提前致谢!
我正在使用 CameraX 在我的 android 应用程序中拍照,保存它们,然后从它们的路径中显示它们。在之前的 alpha-09 版本中,我可以使用 onImageSaved(File file) 来做到这一点。但是,对于 alpha-10,我必须使用 onImageSaved(OutputFileResults outputFileResults),然后从 outputFileResults 检索的 uri 中获取路径。但是我得到的 Uri 总是错误的。例如,当我的图像保存在:“/external/images/media/1581680878237.jpg”时,我得到 uri 的路径:“/external/images/media/113758”。
这是我的代码:
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "NEW_IMAGE");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(
activity.getContentResolver(),
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues).build();
imageCapture.takePicture(outputFileOptions, Runnable::run, new ImageCapture.OnImageSavedCallback() {
@Override
public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
Uri uri = outputFileResults.getSavedUri();
if(uri != null){
System.out.println("URI PATH" + uri.getPath());
System.out.println("URI PATH" + uri.toString());
activity.runOnUiThread(cameraProvider::unbindAll);
galleryAddPic(uri);
Bundle params = new Bundle();
params.putString("FILE_PATH", uri.getPath());
Navigation.findNavController(root).navigate(R.id.navigation_edit_image, params);
}
}
@Override …Run Code Online (Sandbox Code Playgroud) 我不知道如何在预览视图中使用 camerax。
我正在使用 CameraX
这是我的图像捕获:
mImageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.setTargetAspectRatio(screenAspectRatio)
.build()
Run Code Online (Sandbox Code Playgroud)
图像捕捉监听器:
mImageCapture.takePicture(
executor!!,
object : ImageCapture.OnImageCapturedCallback() {
override fun onCaptureSuccess(image: ImageProxy) {
Log.d("AAAA", "Success")
val rotatedBitmap = bitmapHelper.rotateImage(
bitmapHelper.imageToBitmap(image = image.image!!),
image.imageInfo.rotationDegrees.toFloat()
)
runOnUiThread {
mImageView.setImageBitmap(rotatedBitmap)
}
}
override fun onError(
imageCaptureError: Int,
message: String,
cause: Throwable?
) {
2
super.onError(imageCaptureError, message, cause)
}
})
Run Code Online (Sandbox Code Playgroud)
当我调用takePicture应用程序冻结时,仅在 3-4 秒后 onCaptureSuccess 调用
我怎样才能使这个过程更快?
有没有办法使用 查询可用的相机分辨率CameraX?随着Camera2这是可能使用StreamConfigurationMap.getOutputSizes() 。但是,我找不到使用CameraX.
文档已经过时并没有帮助。目前它引用了版本,1.0.0-alpha06并且许多 API 在最新的1.0.0-beta01.
编辑:
有一种方法可以使用Camera2API获得可用的分辨率(感谢下面的 Wasim 回答)。但是,这只有在相机绑定到生命周期之后才有可能,因此无法再更改目标分辨率,这使得它非常无用。
当然,我可以在不知道可用分辨率的情况下指定目标分辨率,但这样我就无法控制最终的纵横比。在我的情况下,我最终得到了 16:9Preview和 4:3,ImageAnalysis尽管targetResolution我的ImageAnalysis是 16:9 (224x126)。
作为记录,这是获得输出大小的方法:
val camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalyzer)
val cameraId = Camera2CameraInfo.extractCameraId(camera.cameraInfo)
val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
val streamConfigurationMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
val outputSizes = streamConfigurationMap.getOutputSizes(format)
Run Code Online (Sandbox Code Playgroud)
仍在寻找实际解决方案。提前致谢。
我正在尝试为我的屏幕录像机应用程序制作浮动相机视图。
FloatingViewService.java
public class FloatingViewService extends LifecycleService implements CameraXConfig.Provider, LifecycleOwner {
private View mFloatingView;
private WindowManager mWindowManager;
PreviewView previewView;
private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
public FloatingViewService() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
super.onBind(intent);
return null;
}
@Override
public void onCreate() {
super.onCreate();
mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);
final WindowManager.LayoutParams params;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
} else {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
}
params.width = 400; …Run Code Online (Sandbox Code Playgroud) java android android-lifecycle android-camerax lifecycleowner
在相机 1 中,我们有FaceDetectionListener方法camera.startFaceDetection()。使用这种方式可以更容易地找到面孔。
在相机 2 中,我们可以使用 CameraCaptureSession.CaptureCallback() 方法和此静态变量执行相同操作
Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE);
Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
Run Code Online (Sandbox Code Playgroud)
现在有一个名为 CameraX 的新相机库。它是Camera2的包装,推荐使用。如果是Camera 2的封装,我们可以很容易得到如下的回调结果CameraCaptureSession.CaptureCallback()
但经过三天的尝试,我未能找到解决方案。
谁能给我像camera2一样调用以下方法的解决方案?
在相机2中,
private val mCaptureCallback = object : CameraCaptureSession.CaptureCallback() {
override fun onCaptureProgressed(
session: CameraCaptureSession,
request: CaptureRequest,
partialResult: CaptureResult
) {
}
override fun onCaptureCompleted(
session: CameraCaptureSession,
request: CaptureRequest,
result: TotalCaptureResult
) {
}
}
mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
mBackgroundHandler);
Run Code Online (Sandbox Code Playgroud)
如何使用CameraX获取回调结果?