I'm building a simple application which acts similar to built-in camera application - takes a photo and saves it locally, with some additional aсtions. First I took Firemonkeys' TCameraComponent
, placed it to the form and added transfered image from it to TImage
. It works OK, I can change resolution, control flash power and so on. The problem is that preview framerate is very low while running at good quality. If I switch camera to 320x240 resolution, it works fast enough, but quality is poor and I have to switch to some higher resolution to take a good photo - loosing time on re-focusing and light adaptation. If I set high resolution (such as 1280x720) for preview, it slows down to about 3-5 fps.
So I need to use some another technique to access camera. App interface must still unchanged during usage, so I can't use TakePhotoFromCameraAction
. I'm looking to JNI interfaces. So I need, using JNI calls, access camera and get a preview at some image object at my form. I use the such code to get preview (I'm a bit lack of understanding native android so it may look crazy):
J.Cam := TJCamera.JavaClass.open(0); // J.Cam is JCamera object
J.View := TJView.JavaClass.init( TAndroidHelper.Context ); // JView
J.ViewParams := TJViewGroup_LayoutParams.JavaClass.init(Width, Height); // i got Width and Height from J.Cam.getParameters()
TAndroidHelper.Activity.addContentView( J.View, J.ViewParams );
J.SurfaceView := TJSurfaceView.JavaClass.init( J.View.getContext );
J.LayoutParameters := TJViewGroup_LayoutParams.JavaClass.init(Width, Height);
J.SurfaceView.setLayoutParams( J.LayoutParameters );
J.Cam.setPreviewDisplay( J.SurfaceView.getHolder );
J.Cam.startPreview;
and it doesn't show anything except black screen. Google developer reference says that "If you are using SurfaceView
, you will need to register a SurfaceHolder.Callback
with addCallback(SurfaceHolder.Callback)
and wait for surfaceCreated(SurfaceHolder)
before calling setPreviewDisplay()
or starting preview."
So the next step I should create the callback class, extending SurfaceView and implementing SurfaceHolder.Callback. There are many samples can be found like this:
public class TestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new MySurfaceView(this));
}
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
public MySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }
@Override
public void surfaceCreated(SurfaceHolder holder) { }
@Override
public void surfaceDestroyed(SurfaceHolder holder) { }
}
}
Now a have to translate this code to Delphi. Java code is classes only, but Delphi's JNI is interfaces AND classes so I can't figure out how to represent this:
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback
since both JNI's JSurfaceView
and JSurfaceHolder_Callback
are interfaces.
So, does anybody knows how do do this? (or completely another way to access camera)