CameraSelector.Builder().AddCameraFilter effectively unusable (cannot select specific camera lens)
Closed this issue · 2 comments
Android application type
Android for .NET (net6.0-android, etc.)
Affected platform version
Xamarin.AndroidX.Camera.Core 1.3.1.1
Description
To choose a specific camera lens (NOT default front or back), we would use code like this:
var selector = new CameraSelector.Builder()
.AddCameraFilter( <your filter here - how do we use this?> )
.Build()
and then pass that into cameraProvider.BindToLifecycle
.
The Kotlin code would look like:
val selector = CameraSelector.Builder()
.addCameraFilter { cameras -> camera.first { someSelector(it) } }
.build()
The camera filter is type ICameraFilter
, which has a method List<ICameraInfo> filter(ICameraInfo cameras)
.
However, this is very difficult, impossible, or very unintuitive to use - I haven't been able to figure it out.
Lambdas don't work. Subclassing requires implementing a boatload of JNI-related methods. All sample code online I've found doesn't use AddCameraFilter
, only RequireLensFacing
.
Steps to Reproduce
- This is not my project, but should be a working CameraX sample project: https://github.com/v-hogood/CameraXSamples/tree/master
- Navigate to
CameraActivity
(https://github.com/v-hogood/CameraXSamples/blob/9aac3649fa8bdd247ca6828d8940e6a0deaef5eb/CameraXTfLite/CameraActivity.cs#L161). - Pretend that you have already queried the device to find a physical camera lens with id
3
. - Try to modify
new CameraSelector.Builder().RequireLensFacing(lensFacing).Build();
so that it specifically selects theCameraInfo
with lens id3
. The way to do this is withAddCameraFilter
.
Did you find any workaround?
No workaround found.
Relevant log output
No response
I think it would be something like:
var selector = new CameraSelector.Builder ()
.AddCameraFilter (new MyCameraFilter ())
.Build ();
class MyCameraFilter : Java.Lang.Object, ICameraFilter {
public IList<ICameraInfo> Filter (IList<ICameraInfo> p0) => p0.Where (c => c.LensFacing == 3);
}
That works perfectly. : Java.Lang.Object,
was the missing key.
Thank you so much. Up to you whether to leave this open; I did ask for help on a large C# Discord server and nobody who answered could figure it out either.
Note to anyone finding this later:
The list you return from filter
must be modifiable (the Java implementation calls retainAll
on it).
Therefore, simply returning the same list passed in (p0
) will result in a Java.Lang.UnsupportedOperationException
. Calling ToList()
on it fixes it.
Also, LensFacing
is not the same as the lens id. There doesn't seem to be a way to get that directly from CameraInfo
, so you'll need to store that mapping in memory elsewhere and do a lookup.