我正在构建一个类似于内置相机应用程序的简单应用程序 - 拍摄照片并将其保存在本地,并附加一些额外的操作。首先,我使用Firemonkeys TCameraComponent
,将其放置在表单中,然后将转移后的图像添加到TImage
。它工作正常,我可以改变分辨率,控制闪光灯电源等。问题是预览帧率非常低,同时运行质量很好。如果我将相机切换到320x240分辨率,它的工作速度足够快,但质量很差,我必须切换到更高的分辨率才能拍出好照片 - 在重新聚焦和光线适应时会浪费时间。如果我设置高分辨率(例如1280x720)进行预览,它会减慢到大约3-5 fps。
所以我需要使用另一种技术来访问相机。应用程序界面在使用期间必须保持不变,因此我无法使用TakePhotoFromCameraAction
。我正在寻找JNI接口。因此,我需要使用JNI调用访问摄像头并在我的表单上的某个图像对象上进行预览。我使用这样的代码来预览(我有点缺乏理解原生android所以它可能看起来很疯狂):
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;
除黑屏外没有显示任何内容。 Google开发人员参考says that“如果您使用SurfaceView
,则需要在SurfaceHolder.Callback
注册addCallback(SurfaceHolder.Callback)
并等待surfaceCreated(SurfaceHolder)
,然后再致电setPreviewDisplay()
或者开始预览。“
所以下一步我应该创建回调类,扩展SurfaceView并实现SurfaceHolder.Callback。有很多样本可以这样找到:
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) { }
}
}
现在必须将此代码翻译为Delphi。 Java代码只是类,但Delphi的JNI是接口AND类,所以我无法弄清楚如何表示:
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback
因为JNI的JSurfaceView
和JSurfaceHolder_Callback
都是接口。
那么,有人知道怎么做吗? (或完全以另一种方式访问相机)