您的位置:首页 > 移动开发 > Android开发

在android中用opencv实现拍照,存储照片的程序源代码

2015-04-21 14:54 274 查看
我用的是opencvforandroid2.4.6,调用opencv自己封装的类来实现拍照功能程序具体流程如下所述:先启动CameraActivity,,屏幕显示摄像头以及两个菜单,一个菜单可以转换摄像头,一个菜单拍照,,当按下拍照菜单后会设置mIsPhotoPending 为true,此后程序自动调用onCameraFrame方法,因为mIsPhotoPending 为true所以可以在onCameraFrame方法中进行照片的保存等工作,由于保存照片很繁琐所以独立用了一个方法takePhoto(),,在该方法中程序会跳转到LabActivity,该activity中有三个菜单,删除,编辑,分享,,可对拍摄好的照片进行这些操作。下面是具体代码,,可以在手机(android4.2以上的系统上)实现
CameraActivity.java
package com.nummist.secondsight;import java.io.File;import org.opencv.android.BaseLoaderCallback;import org.opencv.android.CameraBridgeViewBase;import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;import org.opencv.android.LoaderCallbackInterface;import org.opencv.android.NativeCameraView;import org.opencv.android.OpenCVLoader;import org.opencv.core.Core;import org.opencv.core.Mat;import org.opencv.highgui.Highgui;import org.opencv.imgproc.Imgproc;import com.nummist.secondsight.filters.Filter;import com.nummist.secondsight.filters.NoneFilter;import com.nummist.secondsight.filters.convolution.StrokeEdgesFilter;import com.nummist.secondsight.filters.curve.CrossProcessCurveFilter;import com.nummist.secondsight.filters.curve.PortraCurveFilter;import com.nummist.secondsight.filters.curve.ProviaCurveFilter;import com.nummist.secondsight.filters.curve.VelviaCurveFilter;import com.nummist.secondsight.filters.mixer.RecolorCMVFilter;import com.nummist.secondsight.filters.mixer.RecolorRCFilter;import com.nummist.secondsight.filters.mixer.RecolorRGVFilter;import android.hardware.Camera;import android.hardware.Camera.CameraInfo;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.provider.MediaStore.Images;import android.annotation.SuppressLint;import android.app.Activity;import android.content.ContentValues;import android.content.Intent;import android.support.v4.app.FragmentActivity;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.Window;import android.view.WindowManager;import android.widget.Toast;public class CameraActivity extends FragmentActivityimplements CvCameraViewListener2 {// A tag for log output.//一个标记为日志输出private static final String TAG = "MainActivity";// A key for storing the index of the active camera.//一个关键的,用于存储有效的照相机的索引。private static final String STATE_CAMERA_INDEX = "cameraIndex";// The index of the active camera.//活动摄像头的索引private int mCameraIndex;// Whether the active camera is front-facing.//活动相机是前置// If so, the camera view should be mirrored.//如果是这样,相机视图要显示private boolean mIsCameraFrontFacing;// The number of cameras on the device.//这个数表示设备上相机的数量private int mNumCameras;// The camera view.private CameraBridgeViewBase mCameraView;// Whether the next camera frame should be saved as a photo.//无论下一相机框架是哪一个都应该保存照片private boolean mIsPhotoPending;// A matrix that is used when saving photos.//一个矩阵是用于保存照片的private Mat mBgr;//Whether an asynchronous menu action is in progress.//If so, menu interaction should be disabled.//如果一个菜单在进行,菜单交互应该被禁止private boolean mIsMenuLocked;//The OpenCV loader callback.//Opencv 程序回调private BaseLoaderCallback mLoaderCallback =new BaseLoaderCallback(this) {@Overridepublic void onManagerConnected(final int status) {switch (status) {case LoaderCallbackInterface.SUCCESS:Log.d(TAG, "OpenCV loaded successfully");mCameraView.enableView();mBgr = new Mat();break;default:super.onManagerConnected(status);break;}}};@SuppressLint("NewApi")@Overrideprotected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);final Window window = getWindow();window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);if (savedInstanceState != null) {mCameraIndex = savedInstanceState.getInt(STATE_CAMERA_INDEX, 0);} else {mCameraIndex = 0;mCurveFilterIndex = 0;mMixerFilterIndex = 0;mConvolutionFilterIndex = 0;}if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.GINGERBREAD) {CameraInfo cameraInfo = new CameraInfo();Camera.getCameraInfo(mCameraIndex, cameraInfo);mIsCameraFrontFacing =(cameraInfo.facing ==CameraInfo.CAMERA_FACING_FRONT);mNumCameras = Camera.getNumberOfCameras();} else { // pre-Gingerbread// Assume there is only 1 camera and it is rear-facing.mIsCameraFrontFacing = false;mNumCameras = 1;}mCameraView = new NativeCameraView(this, mCameraIndex);mCameraView.setCvCameraViewListener(this);setContentView(mCameraView);}public void onSaveInstanceState(Bundle savedInstanceState) {// Save the current camera index.savedInstanceState.putInt(STATE_CAMERA_INDEX, mCameraIndex);savedInstanceState.putInt(STATE_CURVE_FILTER_INDEX,mCurveFilterIndex);savedInstanceState.putInt(STATE_MIXER_FILTER_INDEX,mMixerFilterIndex);savedInstanceState.putInt(STATE_CONVOLUTION_FILTER_INDEX,mConvolutionFilterIndex);super.onSaveInstanceState(savedInstanceState);}@Overridepublic void onPause() {if (mCameraView != null) {mCameraView.disableView();}super.onPause();}@Overridepublic void onResume() {super.onResume();OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3,this, mLoaderCallback);mIsMenuLocked = false;}@Overridepublic void onDestroy() {super.onDestroy();if (mCameraView != null) {mCameraView.disableView();}}@Overridepublic boolean onCreateOptionsMenu(final Menu menu) {getMenuInflater().inflate(R.menu.activity_camera, menu);if (mNumCameras < 2) {// Remove the option to switch cameras, since there is// only 1.menu.removeItem(R.id.menu_next_camera);}return true;}@SuppressLint("NewApi")@Overridepublic boolean onOptionsItemSelected(final MenuItem item) {if (mIsMenuLocked) {return true;}switch (item.getItemId()) {case R.id.menu_next_curve_filter:mCurveFilterIndex++;if (mCurveFilterIndex == mCurveFilters.length) {mCurveFilterIndex = 0;}return true;case R.id.menu_next_mixer_filter:mMixerFilterIndex++;if (mMixerFilterIndex == mMixerFilters.length) {mMixerFilterIndex = 0;}return true;case R.id.menu_next_convolution_filter:mConvolutionFilterIndex++;if (mConvolutionFilterIndex ==mConvolutionFilters.length) {mConvolutionFilterIndex = 0;}return true;case R.id.menu_next_camera:mIsMenuLocked = true;// With another camera index, recreate the activity.//另一个相机索引,重新创建活动mCameraIndex++;if (mCameraIndex == mNumCameras) {mCameraIndex = 0;}recreate();return true;case R.id.menu_take_photo:mIsMenuLocked = true;// Next frame, take the photo.//mIsPhotoPending = true;return true;default:return super.onOptionsItemSelected(item);}}private void takePhoto(final Mat rgba) {// Determine the path and metadata for the photo.//确定路径和照片元数据final long currentTimeMillis = System.currentTimeMillis();final String appName = getString(R.string.app_name);final String galleryPath =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();final String albumPath = galleryPath + "/" + appName;final String photoPath = albumPath + "/" +currentTimeMillis + ".png";final ContentValues values = new ContentValues();values.put(MediaStore.MediaColumns.DATA, photoPath);values.put(Images.Media.MIME_TYPE,LabActivity.PHOTO_MIME_TYPE);values.put(Images.Media.TITLE, appName);values.put(Images.Media.DESCRIPTION, appName);values.put(Images.Media.DATE_TAKEN, currentTimeMillis);// Ensure that the album directory exists.//确保相片目录存在File album = new File(albumPath);if (!album.isDirectory() && !album.mkdirs()) {Log.e(TAG, "Failed to create album directory at " +albumPath);onTakePhotoFailed();return;}// Try to create the photo.//尝试创建照片Imgproc.cvtColor(rgba, mBgr, Imgproc.COLOR_RGBA2BGR, 3);if (!Highgui.imwrite(photoPath, mBgr)) {Log.e(TAG, "Failed to save photo to " + photoPath);//图片没有保存到onTakePhotoFailed();}Log.d(TAG, "Photo saved successfully to " + photoPath);//图片保存成功// Try to insert the photo into the MediaStore.//尝试插入图片到MediaStoreUri uri;try {uri = getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);} catch (final Exception e) {Log.e(TAG, "Failed to insert photo into MediaStore");//无法插入图像到MediaStoree.printStackTrace();// Since the insertion failed, delete the photo.//由于插入失败,删除图片File photo = new File(photoPath);if (!photo.delete()) {Log.e(TAG, "Failed to delete non-inserted photo");}onTakePhotoFailed();return;}// Open the photo in LabActivity.//打开照片在LabActivityfinal Intent intent = new Intent(this, LabActivity.class);intent.putExtra(LabActivity.EXTRA_PHOTO_URI, uri);intent.putExtra(LabActivity.EXTRA_PHOTO_DATA_PATH,photoPath);startActivity(intent);}private void onTakePhotoFailed() {mIsMenuLocked = false;// Show an error message.// 显示一个错误消息final String errorMessage =getString(R.string.photo_error_message);runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(CameraActivity.this, errorMessage,Toast.LENGTH_SHORT).show();}});}@Overridepublic void onCameraViewStarted(int width, int height) {// TODO Auto-generated method stub}@Overridepublic void onCameraViewStopped() {// TODO Auto-generated method stub}@Overridepublic Mat onCameraFrame(CvCameraViewFrame inputFrame) {final Mat rgba = inputFrame.rgba();if (mIsPhotoPending) {mIsPhotoPending = false;takePhoto(rgba);}if (mIsCameraFrontFacing) {// Mirror (horizontally flip) the preview.Core.flip(rgba, rgba, 1);}return rgba;}}
LabActivity.java
package com.nummist.secondsight;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.provider.MediaStore;import android.provider.MediaStore.Images;import android.view.Menu;import android.view.MenuItem;import android.widget.ImageView;public class LabActivity extends Activity {public static final String PHOTO_MIME_TYPE = "image/png";public static final String EXTRA_PHOTO_URI ="com.nummist.secondsight.LabActivity.extra.PHOTO_URI";public static final String EXTRA_PHOTO_DATA_PATH ="com.nummist.secondsight.LabActivity.extra.PHOTO_DATA_PATH";private Uri mUri;private String mDataPath;@Overrideprotected void onCreate(final Bundle savedInstanceState) {super.onCreate(savedInstanceState);final Intent intent = getIntent();mUri = intent.getParcelableExtra(EXTRA_PHOTO_URI);mDataPath = intent.getStringExtra(EXTRA_PHOTO_DATA_PATH);final ImageView imageView = new ImageView(this);imageView.setImageURI(mUri);setContentView(imageView);}@Overridepublic boolean onCreateOptionsMenu(final Menu menu) {getMenuInflater().inflate(R.menu.activity_lab, menu);return true;}@Overridepublic boolean onOptionsItemSelected(final MenuItem item) {switch (item.getItemId()) {case R.id.menu_delete:deletePhoto();return true;case R.id.menu_edit:editPhoto();return true;case R.id.menu_share:sharePhoto();return true;default:return super.onOptionsItemSelected(item);}}private void deletePhoto() {final AlertDialog.Builder alert = new AlertDialog.Builder(LabActivity.this);alert.setTitle(R.string.photo_delete_prompt_title);alert.setMessage(R.string.photo_delete_prompt_message);alert.setCancelable(false);//按返回键不能退出alert.setPositiveButton(R.string.delete,new DialogInterface.OnClickListener() {@Overridepublic void onClick(final DialogInterface dialog,final int which) {getContentResolver().delete(Images.Media.EXTERNAL_CONTENT_URI,MediaStore.MediaColumns.DATA + "=?",new String[] { mDataPath });finish();}});alert.setNegativeButton(android.R.string.cancel, null);alert.show();}private void editPhoto() {final Intent intent = new Intent(Intent.ACTION_EDIT);intent.setDataAndType(mUri, PHOTO_MIME_TYPE);startActivity(Intent.createChooser(intent,getString(R.string.photo_edit_chooser_title)));}private void sharePhoto() {final Intent intent = new Intent(Intent.ACTION_SEND);intent.setType(PHOTO_MIME_TYPE);intent.putExtra(Intent.EXTRA_STREAM, mUri);intent.putExtra(Intent.EXTRA_SUBJECT,getString(R.string.photo_send_extra_subject));intent.putExtra(Intent.EXTRA_TEXT,getString(R.string.photo_send_extra_text));startActivity(Intent.createChooser(intent,getString(R.string.photo_send_chooser_title)));}}
layout\\gg.xml<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><org.opencv.android.JavaCameraViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:id="@+id/color_blob_detection_activity_surface_view" /></LinearLayout>
menu\\activity_camera.xml
<pre name="code" class="html"><menu xmlns:android="http://schemas.android.com/apk/res/android" ><itemandroid:id="@+id/menu_next_camera"android:orderInCategory="100"android:showAsAction="ifRoom|withText"android:title="@string/menu_next_camera"/><itemandroid:id="@+id/menu_take_photo"android:orderInCategory="100"android:showAsAction="always|withText"android:title="@string/menu_take_photo"/></menu>
menu\\activi_lab.xml
menu\\activi_lab.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" ><itemandroid:id="@+id/menu_delete"android:orderInCategory="100"android:showAsAction="ifRoom|withText"android:title="@string/delete" /><item    android:id="@+id/menu_edit"android:orderInCategory="100"android:showAsAction="ifRoom|withText"android:title="@string/edit" /><itemandroid:id="@+id/menu_share"android:orderInCategory="100"android:showAsAction="ifRoom|withText"android:title="@string/share" /></menu>
</pre><pre name="code" class="html">配置文件的代码
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.nummist.secondsight"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="18" /><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-feature android:name="android.hardware.camera" /><uses-feature android:name="android.hardware.camera.autofocus"android:required="false" /><uses-feature android:name="android.hardware.camera.flash"android:required="false" />    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.nummist.secondsight.CameraActivity"            android:label="@string/app_name"             android:screenOrientation="landscape">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activityandroid:name="com.nummist.secondsight.LabActivity"android:label="@string/app_name"android:screenOrientation="landscape"></activity>    </application></manifest>
</pre><pre name="code" class="html">

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: