Jump to content
KMarb

delphi camera focus

Recommended Posts

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

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
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

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

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
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
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 by Dave Nottage

Share this post


Link to post

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 by programmerdelphi2k

Share this post


Link to post
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

  • Like 3

Share this post


Link to post

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.

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×