本文将讨论用Qt访问Android摄像头(或者说默认摄像头接口)所需要的步骤。很遗憾,自4.5版本以后OpenCV不再提供访问原生(Native C++)摄像头的库稳定方法,如果你想用Qt开发Android OpenCV程序的话,本文显然就是你要找的。强烈推荐你先阅读这篇文章(描述如何用Qt和Java代码混合编程)和这篇文章(如何用Qt打开Android图像库)然后再返回这里阅读,因为在此假设你已经熟悉这个流程。所以,如果你已经熟悉了用Qt访问Android图库,然后继续阅读下面描述的步子。


访问摄像头的方法和代码除了从AndroidManifest.xml文件开始以后的外,几乎所有的步子都跟访问Android图库一样。你可以通过在AndroidManifest.xml文件中添加如下代码添加摄像头访问许可。


下一步,需要你建一个简单的Qt函数来初始化Camera(capture)函数。Camera函数将采用Java程序实现,而在Qt C++程序中调用。就像这样:

QAndroidJniObject::callStaticMethod(“com/amin/QtAndroidCameraApp/QtAndroidCameraApp”,“captureAnImage”,“()V”);

注意QtAndroidCameraApp是我给出的名字,你可以按照你的app名称来自己命名。

再次,正如访问图库一样,需要写一个JNI函数类读取Java返回的selectedFileName变量,如下:

JNIEXPORT void JNICALLJava_com_amin_QtAndroidCameraApp_QtAndroidCameraApp_fileSelected(JNIEnv */*env*/,jobject /*obj*/,jstring results){selectedFileName = QAndroidJniObject(results).toString();}

最后,需要在你的java代码中加入如下程序:

captureAnImage函数将会在C++程序中调用。它需要被声明成不带参数的静态函数:

static void captureAnImage(){m_instance.dispatchTakePictureIntent();}



m_instance函数总是指向“this”类,调用 dispatchTakePictureIntent来启动摄像头接口:

private void dispatchTakePictureIntent(){Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// Ensure that there’s a camera activity to handle the intentif (takePictureIntent.resolveActivity(getPackageManager()) != null){// Create the File where the photo should goFile photoFile = null;try{photoFile = m_instance.createImageFile();}catch (IOException ex){// Error occurred while creating the FileToast.makeText(QtAndroidCameraApp.this, ex.getLocalizedMessage(), Toast.LENGTH_LONG).show();Toast.makeText(QtAndroidCameraApp.this, ex.getMessage(), Toast.LENGTH_LONG).show();}// Continue only if the File was successfully createdif (photoFile != null){takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));lastCameraFileUri = photoFile.toString();startActivityForResult(takePictureIntent, REQUEST_CAPTURE_IMAGE);}}else{Toast.makeText(QtAndroidCameraApp.this, “Problems with your camera?!”, Toast.LENGTH_SHORT).show();}}
已更新:新增漏掉的函数createImageFile

上文提到的createImageFile函数需要这样定义:

private File createImageFile() throws IOException{// Create an image file nameString timeStamp = new SimpleDateFormat(“yyyyMMdd_HHmmss”).format(new Date());String imageFileName = “MYAPPTEMP_” + timeStamp + “_”;File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);File image = File.createTempFile(imageFileName, /* prefix */“.jpg”, /* suffix */storageDir /* directory */);return image;}

尽管乍一看比较复杂,其实很简单。你启动摄像头然后等待它返回结果。如果返回结果正确,返回结果,在C++中将捕获这个,结果。否则,只需要显示一些错误信息并推出。可能你会注意到:dispatchTakePictureIntent调用了一些变量和函数,这些东西定义如下:


很明显第一个是lastCameraFileUri:

public String lastCameraFileUri;

接着是 REQUEST_CAPTURE_IMAGE,它你定义的一个常量,用以确保你在activity接收到的结果是摄像头拍出来的:

static final int REQUEST_CAPTURE_IMAGE = 1;


最后你需要override onActivityResult函数:

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data){if (resultCode == RESULT_OK){if(requestCode == REQUEST_CAPTURE_IMAGE){String filePath = lastCameraFileUri;fileSelected(filePath);}}else{fileSelected(“:(“);}super.onActivityResult(requestCode, resultCode, data);}

fileSelected函数需要被定义成native函数,因为就像你看到的,它从C++调用的文件名。唯一要做的事情就是做如下文的定义。函数的内容在你前面写的C++ Qt程序中

public static native void fileSelected(String fileName);

收工。 



更多相关文章

  1. android Activity setTheme() 更改主题
  2. 安卓反编译揭秘(爱加密系列教程九)
  3. android app中如何获取电源锁保持屏幕常亮
  4. 如何安装Android应用程序到sdcard上
  5. 加速Android(安卓)UI(一):加速ListView
  6. Kivy A to Z -- 调试篇之在Android平台调试Python代码
  7. Flutter教程(一) 十分钟了解Flutter
  8. Android(安卓)== 简单的binder通信
  9. Android显示原理

随机推荐

  1. Android(安卓)---- WebView与JavaScript
  2. Android(安卓)异步开发之 AsyncQueryHand
  3. 利用ViewDragHelper轻松实现Android拼图
  4. AndroidStudio3.4+ 导入旧版本moudle出现
  5. Android画布和图形绘制---Canvas and Dra
  6. Android(安卓)Studio项目将Module依赖(lib
  7. Android.mk文件语法规范及使用模板
  8. 自定义 ProgressBar 进度条 自定义样式
  9. Android单元测试,模拟http的get和post请求
  10. Android(安卓)xutil3.0完全解析