This is a weird issue . I don't know whether it is a bug or something in the library .So the issue is with flash of the camerax .
I assign a global variable flashMode
private var flashMode: Int = ImageCapture.FLASH_MODE_OFF
then set it to the ImageCaptureBuilder
imageCapture = ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.setTargetAspectRatio(screenAspectRatio)
.setFlashMode(flashMode)
.setTargetRotation(rotation)
.build()
And before taking the picture I turn the flash On
if (camera?.cameraInfo?.hasFlashUnit() == true) {
flashMode = ImageCapture.FLASH_MODE_ON
}
But this does Not turn the camera flash On , but it sets the flashMode value to 1 ,i.e.,ImageCapture.FLASH_MODE_ON (I checked via logging ).Before capturing the image , i again logged and checked the value of flashMode and it was 1 , but then too the flash was not turning on.But if I set the global variable as
private var flashMode: Int = ImageCapture.FLASH_MODE_ON
Then it works and the flash get's turned on .
I have tried this above method of setting the Flash On post setting it to FlashModeOff in my previous projects and it had worked well . But this time I am not able to understand what is wrong .
Thanks in advance
Try changing the flash mode with
imageCapture.flashMode = ImageCapture.FLASH_MODE_ON
instead of
flashMode = ImageCapture.FLASH_MODE_ON
Im using JAVA
private void ativarFlash() {
ic_flash.startAnimation(animationDown);
if (flashMode == FlashMode.ON) {
flashMode = FlashMode.OFF;
} else {
flashMode = FlashMode.ON;
}
startCamera();
}
And on startCamera();
private void startCamera() {
CameraX.unbindAll();
preview = setPreview();
imageCapture = setImageCapture();
//bind to lifecycle:
CameraX.bindToLifecycle(this, preview, imageCapture);
ivBitmap.setImageDrawable(null);
}
Related
I have problem with Camera2 api, I want to get back cameraID, but CameraManager return only front camera. Device should have two cameras (front and back), but Manager return only front. Problem occurs always on Pixel 5 with Android 11
fun getBackCamera(): String {
val cameraManager =
requireContext().getSystemService(Context.CAMERA_SERVICE) as CameraManager
val allCameraIds = cameraManager.cameraIdList
return allCameraIds.first { cameraId ->
cameraManager.getCameraCharacteristics(cameraId)
.get(CameraCharacteristics.LENS_FACING)!! == CameraCharacteristics.LENS_FACING_BACK
}
}
Something changed in API? I want to have back camera id. Thank you for help 🙂
I would like to get the value of the current gains and change the value of the RGB gains.
In iOS, Apple provides setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains:completionHandler.
- (void)setWhiteBalanceGains:(AVCaptureWhiteBalanceGains)gains
{
NSError *error = nil;
if ( [self.captureDevice lockForConfiguration:&error] ) {
AVCaptureWhiteBalanceGains normalizedGains = [self normalizedGains:gains];
[self.captureDevice setWhiteBalanceModeLockedWithDeviceWhiteBalanceGains:normalizedGains completionHandler:nil];
[self.captureDevice unlockForConfiguration];
}
else {
NSLog( #"Could not lock device for configuration: %#", error );
}
}
- (AVCaptureWhiteBalanceGains)normalizedGains:(AVCaptureWhiteBalanceGains) g
{
AVCaptureWhiteBalanceGains gains = g;
gains.redGain = MAX(gains.redGain, 1.0f);
gains.greenGain = MAX(gains.greenGain, 3.0f);
gains.blueGain = MAX(gains.blueGain, 18.0f);
return gains;
}
How can we achieve this in android using cameraX?
COLOR_CORRECTION_GAINS
COLOR_CORRECTION_MODE
I have checked in the doc regarding channel control. But how can we change color correction and reset the cameraX preview with the new control?
You can use Camera2Interop:
fun buildPreview() : Preview {
val builder = Preview.Builder()
val camera2InterOp = Camera2Interop.Extender(builder)
camera2InterOp.setCaptureRequestOption(CaptureRequest. COLOR_CORRECTION_MODE, CameraMetadata.COLOR_CORRECTION_MODE_FAST)
return builder.build()
}
Old but still used is the class Camera.Parameters#getWhiteBalance
https://developer.android.com/reference/android/hardware/Camera.Parameters#getWhiteBalance()
Using class Camera.Parameters call getWhiteBalance.
The newer way is to use Capture request https://developer.android.com/reference/android/hardware/camera2/CaptureRequest
Here is the full documentation of Camera2
https://developer.android.com/reference/android/hardware/camera2/package-summary
I use Camera X and trying to lock AF and AE using FocusMeteringAction, AF locking fine but AE doesn't lock. What can be a reason?
camerax_version = "1.1.0-alpha02"
val factory: MeteringPointFactory = previewView.meteringPointFactory
val point: MeteringPoint = factory.createPoint(x, y)
val builder = FocusMeteringAction.Builder(point)
builder.disableAutoCancel()
camerax?.cameraControl?.startFocusAndMetering(builder.build())
The code snippet is simple, and the ListenableFuture from startFocusAndMetering() returns a successful result, but AE still dynamic and not locked.
The result I am expecting:
Then point the app towards something bright (eg. the sun or bright light) then lock the exposure. Then move the camera away from the light and everything will be super dark. This shows that the camera is not automatically adjusting the exposure (because it is locked).
My actual result is:
Exposure adjusting and the picture is light/normal.
Would be grateful for any ideas!
Thanks in advance!
It's been a long time but this might be helpful to someone may ended up here.
I don't know if it is possible by using only CameraX apis. But I've achieved the expected behaviour with Camera2 apis. With the below snippet, the AF and AE can be measured and updated with a tap and stays locked afterwards until another tap occures.
private void initTapToFocus() {
previewView.setOnTouchListener((v, event) -> {
MeteringPointFactory meteringPointFactory = previewView.getMeteringPointFactory();
MeteringPoint point = meteringPointFactory.createPoint(event.getX(), event.getY());
FocusMeteringAction action = new FocusMeteringAction
.Builder(point, FocusMeteringAction.FLAG_AF)
.addPoint(point, FocusMeteringAction.FLAG_AE)
.disableAutoCancel()
.build();
//Unlock AE before the tap so it can be updated.
lockAe(false, () -> doFocusAndMetering(action));
return true;
});
}
private void doFocusAndMetering(FocusMeteringAction builder) {
ListenableFuture<FocusMeteringResult> future = cameraControl.startFocusAndMetering(builder);
//Lock AE again when measuring completed
future.addListener(() -> lockAe(true, () -> {}), executor);
}
private void lockAe(boolean lockAe, Runnable doWhenComplete) {
Camera2CameraControl camera2CameraControl = Camera2CameraControl.from(cameraControl);
CaptureRequestOptions options = new CaptureRequestOptions.Builder()
.setCaptureRequestOption(CaptureRequest.CONTROL_AE_LOCK, lockAe)
.build();
camera2CameraControl.setCaptureRequestOptions(options).addListener(doWhenComplete, executor);
}
I am using Pjsip library for SIP Video call. I am facing issue
displying my own view in a SurfaceView.
Here is the image:
Expected View:
Fetching Preview ID in onCallMediaState
mVideoPreview = VideoPreview(mediaInfo.videoCapDev)
mVideoWindow = VideoWindow(mediaInfo.videoIncomingWindowId)
Code I have used to display this preview in my SurfaceView:
fun updateVideoPreview(holder: SurfaceHolder) {
if (SipManager.currentCall != null &&
SipManager.currentCall?.mVideoPreview != null) {
if (videoPreviewActive) {
val vidWH = VideoWindowHandle()
vidWH.handle?.setWindow(holder.surface)
val vidPrevParam = VideoPreviewOpParam()
vidPrevParam.window = vidWH
try {
SipManager.currentCall?.mVideoPreview?.start(vidPrevParam)
} catch (e: Exception) {
println(e)
}
} else {
try {
SipManager.currentCall?.mVideoPreview?.stop()
} catch (e: Exception) {
println(e)
}
}
}
}
I know that the person on other side will always recieve mirror view of my video. But in case of my own view, this should not happen.
What I feel is I am displaying the preview which is sent to the other person. I am not getting a single hint about how to display my own view(without mirror effect) using Pjsip library.
Can anyone please help me with this?
What I did is replaced SurfaceView with TextureView and then check:
if (isFrontCamera) {
val matrix = Matrix()
matrix.setScale(-1.0f, 1.0f)
matrix.postTranslate(width.toFloat(), 0.0f)
surfacePreviewCapture.setTransform(matrix)
}
And it worked.
Hope it help others. :)
====== UPDATE ======
When I checked my back camera, the view was also flipped over there so I need to do this to make it proper:
surfacePreviewCapture.setTransform(null)
Instead of using SurfaceView, you can use TextureView for your preview which you can flipped afterwards. Have a look at How to keep android from inverting the image from the front facing camera? as a reference
I'm current working wits AS3 and Flex 4.6 to create an android application.
i'm using the front camera and attach it to a local Video object that i add as an child to an VideoDisplay object.
When i debug on my computer everything is working perfectly, but when i build the project and run it on my Android device my local video display becomes an gray grid.
As example i took an picture of the device.
I wrote this method based on a post here on Stackoverflow to initialize the front and back camera.
private function InitCamera():void {
var CamCount:int = ( Camera.isSupported ) ? Camera.names.length : 0;
for( var i:int = 0; i < CamCount; i++ ) {
var cam:Camera = Camera.getCamera( String( i ) );
if( cam ) {
if( cam.position == CameraPosition.FRONT ) {
CamFront = cam;
continue;
}
if( cam.position == CameraPosition.BACK ) {
CamBack = cam;
continue;
}
if( cam.position == CameraPosition.UNKNOWN ) {
CamFront = cam;
continue;
}
}
}
}
And i wrote this method to create an Video object, attach the front Camera as the default camera and add the Video as an child to an VideoDisplay:
private function SetUpLocalVideo():void {
Debug( "Setting up local video" );
LocalVideo = new Video( this.LVideo.width, this.LVideo.height );
LocalVideo.attachCamera( CamFront );
LVideo.addChild( LocalVideo ); <--- this is the VideoDisplay
}
I've been searching on the internet for an solution, but so far i failed to find any.
Do any one else had this problem before ? can you share you solutions with me ?
I appreciate the help.
Thanks.
Set the render mode to direct on your application.xml
<renderMode>direct</renderMode>
If it still doesn't work, change the dpi settings to 240 of your main flex application.