KMarb 5 Posted January 4, 2023 I just discovered that some cameras can continuously auto focus and some cannot. Trying to set focusMode to ContinuousAutoFocus blows up the app, in an unrecoverable way... The code below never gets to the except statement: var camera : TCameracomponent; try camera.FocusMode := TFocusMode.ContinuousAutoFocus; except camera.FocusMode := TFocusMode.AutoFocus; end; is there a way to query the camera to find if it supports ContinuousAutoFocus? Or how to make use of continuous auto focus when available? Keith Share this post Link to post
KMarb 5 Posted January 4, 2023 More discovery... I'm finding I get the same error now with this line: camera.FocusMode := TFocusMode.AutoFocus; with some devices and not others. Not sure it matters but I have the component created as a face camera: camera := TCameraComponent.Create (nil); camera.Kind := FMX.Media.TCameraKind.FrontCamera; It seems that some models of phone (or some front cameras) +might not allow me to set focusMode at all... is that correct? Appreciate any thoughts on how to work past this. Share this post Link to post
Dave Nottage 557 Posted January 4, 2023 19 minutes ago, KMarb said: It seems that some models of phone (or some front cameras) +might not allow me to set focusMode at all... is that correct? Most front cameras support fixed (TFocusMode.Locked) only. One way (likely the easiest) to resolve this would be to use a patched FMX.Media.Android unit. Copy the unit to the project folder and change this routine: procedure TAndroidVideoCaptureDevice.SetFocusMode(const AFocusMode: TFocusMode); var Params: JCamera_Parameters; // Patch code vars: LFocusModes: JList; LFocusMode: JString; I: Integer; LIsSupported: Boolean; begin Params := Camera.getParameters; if Params = nil then Exit; // Patch code BEGIN LIsSupported := False; LFocusModes := Params.getSupportedFocusModes; for I := 0 to LFocusModes.size - 1 do begin LFocusMode := TJString.Wrap(LFocusModes.get(I)); if ((AFocusMode = TFocusMode.AutoFocus) and LFocusMode.equals(TJCamera_Parameters.JavaClass.FOCUS_MODE_AUTO)) or ((AFocusMode = TFocusMode.Locked) and LFocusMode.equals(TJCamera_Parameters.JavaClass.FOCUS_MODE_FIXED)) or ((AFocusMode = TFocusMode.ContinuousAutoFocus) and LFocusMode.equals(TJCamera_Parameters.JavaClass.FOCUS_MODE_CONTINUOUS_PICTURE)) then begin LIsSupported := True; Break; end; end; if not LIsSupported then Exit; // Patch code END FFocusMode.Value := AFocusMode; UpdateFocusModeParameter(Params); Camera.setParameters(Params); SetAutoFocus; end; This means that if the mode is not supported, it doesn't try and change it, so it will remain either the default, or the last supported mode it was set to. Share this post Link to post
KMarb 5 Posted January 4, 2023 Thank you very much. One related question... I'm also using the rear camera capability for barcoding. I'm using a single TCameraComponent and flipping between back and front camera. camera.Kind := FMX.Media.TCameraKind.BackCamera; Should I be able to set focusMode for the back camera always, or do some back cameras not handle continuousAutoFocus? I was having problems switching back and forth between the back and front cameras so I changed my code to only set focusMode when I create the TCameracomponent (which is done with kind = FaceCamera), but the bar code reader will not work or not very well unless the focus mode is set. Thanks again. Keith Share this post Link to post
programmerdelphi2k 237 Posted January 4, 2023 I have used this code in my project and for works, of course you needs know "target cam" to query it implementation {$R *.fmx} uses System.Permissions, FMX.Media.Android, Androidapi.Jni.JavaTypes, Androidapi.Jni.Os, Androidapi.Jni.Hardware, Androidapi.Helpers; procedure TForm1.Button1Click(Sender: TObject); var Camera : JCamera; Params : JCamera_Parameters; FocusModeText : string; FocusModeTextToCompare: string; i, j : integer; begin // TJCamera_Parameters.JavaClass.FOCUS_MODE_AUTO // TJCamera_Parameters.JavaClass.FOCUS_MODE_CONTINUOUS_PICTURE // TJCamera_Parameters.JavaClass.FOCUS_MODE_CONTINUOUS_VIDEO // TJCamera_Parameters.JavaClass.FOCUS_DISTANCE_FAR_INDEX ... TJCamera_Parameters.JavaClass.FOCUS_MODE_MACRO // try i := TJCamera.JavaClass.getNumberOfCameras; // if i > 0 then begin try Camera := TJCamera.JavaClass.open(0); // or 1,2,... whos will be your cam target? // Memo1.Lines.Add('CAM opened... = ' + j.ToString); // Params := Camera.getParameters; if (Params <> nil) then begin FocusModeText := JStringToString(Params.getFocusMode); // "auto", "fixed", ... FocusModeTextToCompare := JStringToString(TJCamera_Parameters.JavaClass.FOCUS_MODE_AUTO); // Memo1.Lines.Add('FocusModeText=' + FocusModeText); Memo1.Lines.Add('FocusModeTextToCompare=' + FocusModeTextToCompare); // if (FocusModeText = FocusModeTextToCompare) then Memo1.Lines.Add('CAM has focus_Auto = ' + i.ToString) else Memo1.Lines.Add('CAM has not focus_Auto = ' + i.ToString); end else Memo1.Lines.Add('Params = nil'); except on E: Exception do Memo1.Lines.Add('CAM opening... ' + E.Message); end; end; except on E: Exception do Memo1.Lines.Add(E.Message); end; end; procedure TForm1.FormCreate(Sender: TObject); begin PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.Camera)], nil, nil); end; end. Share this post Link to post
Dave Nottage 557 Posted January 4, 2023 7 minutes ago, KMarb said: do some back cameras not handle continuousAutoFocus? Some do not support it, for example the Samsung S4 apparently does not. Share this post Link to post
Dave Nottage 557 Posted January 4, 2023 (edited) 4 minutes ago, programmerdelphi2k said: I have used this code in my project and for works Yet another wrong answer. This code only compares what the current mode currently is, with auto (which is not one of the continuous modes) - it does not compensate for what modes are supported Edited January 4, 2023 by Dave Nottage Share this post Link to post
programmerdelphi2k 237 Posted January 4, 2023 (edited) for me works, and I dont have problem, then... sorry about your "nothing yet right" you can check the distance if > 0 as said in Android Developer! Camera2 specifications! Edited January 4, 2023 by programmerdelphi2k Share this post Link to post
Dave Nottage 557 Posted January 4, 2023 5 minutes ago, programmerdelphi2k said: sorry about your "nothing yet right" This is a forum for solving problems for other developers. Your answer does not solve the question that was asked. Posting wrong answers only serves to confuse developers that might come across them 3 Share this post Link to post
KMarb 5 Posted January 4, 2023 well, my app is only for a small set of users, and we might have 20 different devices right now. On 3 that I have tested, this works: create: camera := TCameraComponent.Create (nil); camera.Kind := FMX.Media.TCameraKind.FrontCamera; camera.FocusMode := TFocusMode.Locked; when need back camera: if camera.Kind <> FMX.Media.TCameraKind.BackCamera then begin camera.Kind := FMX.Media.TCameraKind.BackCamera; camera.FocusMode := TFocusMode.ContinuousAutoFocus; camera.OnSampleBufferReady := backCameraSampleBufferReady; end; and to flip back to front camera: if camera.Kind <> FMX.Media.TCameraKind.FrontCamera then begin camera.FocusMode := TFocusMode.Locked; camera.Kind := FMX.Media.TCameraKind.FrontCamera; camera.OnSampleBufferReady := frontCameraSampleBufferReady; end; It sounds like some devices (Samsung S4) might fail with the above code, but for the most part this should work. Thank you for the help. 1 Share this post Link to post