博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved !
今天我们来讲一下在Android平台上开发相机的问题!Two choices!
第一种使用intent方法来调用系统方法
一般以动作按钮的方式来操作,101仅作为一个标示
Button button =new Button(this); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub //打开系统相机,拍照数据存在mCurrentPhotoFile里里 Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCurrentPhotoFile)); startActivityForResult(intent, 101); } });
实现Activity里的onActivityResult
/* 反应事件 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //RESULT_OK是个系统变量,代表操作成功,那么我们就可以进行下面的操作了。 if (resultCode != Activity.RESULT_OK) { return; } switch (requestCode) { /* 拍照 */ case 101: //保存了data就保存了图片 super.onActivityResult(requestCode, resultCode, data); break; } }
第二种自定义相机
1、从xml文件中得到surfaceview对象
surfaceView = (SurfaceView) findViewById(R.id.g3_server_preview);
2、之后声明一些回调方法,用于打开相机,设置相机的参数(在这里可以设置图片的尺寸,以及预览界面的尺寸)
// SurfaceHodler 回调,处理打开相机,关闭相机以及照片尺寸的改变 SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { // 打开相机 camera = Camera.open(); try { // 设置预览 camera.setPreviewDisplay(holder); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 获得相机参数 Camera.Parameters parameters = camera.getParameters(); // SDK版本选择,兼容 if (Integer.parseInt(Build.VERSION.SDK) >= 8) { setDisplayOrientation(camera, 90); } else { if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { parameters.set("orientation", "portrait"); parameters.set("rotation", 90); } if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { parameters.set("orientation", "landscape"); parameters.set("rotation", 90); } } // 设置预览大小 parameters.setPreviewSize(width, height); pic_Width = g3_setting.getInt(AppData.G3_PIC_WIDTH, 640); pic_Height = g3_setting.getInt(AppData.G3_PIC_HEIGHT, 800); Log.i("Travel", pic_Width + ":" + pic_Height); // 设置照片大小 parameters.setPictureSize(pic_Width, pic_Height); // 设置照片格式 // parameters.setPictureFormat(PixelFormat.RGB_565); // 开始预览 camera.startPreview(); // 设置相机参数 camera.setParameters(parameters); } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 停止预览 if (camera != null) { camera.stopPreview(); // 释放相机资源 camera.release(); camera = null; } } }; protected void setDisplayOrientation(Camera camera, int angle) { Method downPolymorphic; try { downPolymorphic = camera.getClass().getMethod( "setDisplayOrientation", new Class[] { int.class }); if (downPolymorphic != null) downPolymorphic.invoke(camera, new Object[] { angle }); } catch (Exception e1) { } }
3、然后设置surfaceview参数,加载回调方法
// 设置屏幕常亮 surfaceView.setKeepScreenOn(true); surfaceView.setFocusable(true); releaseCamera(); // 从SurfaceView中获得SurfaceHolder surfaceView.getHolder().addCallback(surfaceCallback); // 为SurfaceHolder 添加回调 // surfaceHolder.addCallback(surfaceCallback); surfaceView.getHolder() .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);释放相机资源
private void releaseCamera() { // TODO Auto-generated method stub if (camera != null) { camera.stopPreview(); // 释放相机资源 camera.release(); camera = null; } }
4、配置相机响声音还是震动的回调方法
Camera.ShutterCallback shutter = new ShutterCallback() { @Override public void onShutter() { // TODO Auto-generated method stub if (tone == null) { // 发出提示用户的声音 tone = new ToneGenerator(AudioManager.STREAM_SYSTEM, ToneGenerator.MAX_VOLUME); } if (g3_setting.getBoolean(AppData.G3_CONFIG_AUDIO, true)) { tone.startTone(ToneGenerator.TONE_PROP_BEEP); } else { tone.stopTone(); Vibrator vibrator = (Vibrator) context .getSystemService(Service.VIBRATOR_SERVICE); vibrator.vibrate(100); } } };
小插曲,判断系统声音能否关闭
File file = new File("/system/media/audio/ui/Camera_click.ogg"); if (!file.canWrite()) { Tools.showToast(context, "设置声音无效!"); } else { file.renameTo(new File("/system/media/audio/ui/Camera_click.ogg1")); }
5、自动对焦并拍照
// 对焦成功再拍照 camera.autoFocus(new AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { // TODO Auto-generated method stub // success为true表示对焦成功 if (success) { if (camera != null) { // 停止预览 camera.stopPreview(); // 拍照 camera.takePicture(shutter, null, pictureCallback); } } } }); // 照片回调 Camera.PictureCallback pictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { Log.i("G3", "picture operating............."); new SavePictureTask().execute(data); camera.startPreview(); } }; // 保存照片任务类 class SavePictureTask extends AsyncTask<byte[], String, String> { @Override protected String doInBackground(byte[]... params) { Log.i("G3", "picture saving............."); File path = new File(Tools.getSDPath()); if (!path.exists()) { path.mkdirs(); } // 创建文件 File picture = new File(Tools.getSDPath(), Tools.initPhotoName()); try { // 获得文件输出流 FileOutputStream fos = new FileOutputStream(picture.getPath()); // 写到该文件 fos.write(params[0]); // 关闭文件流 fos.close(); } catch (Exception e) { e.printStackTrace(); } return null; } }
6、注意事项:
a.本项目代码已经实现对焦功能,如果你的相机不能对焦,那是手机本身不支持,与硬件有关
b.分辨率的设置,在第3步的surfaceChanged方法里已经实现,镜头和设置不能在同一界面,所以如果你实现此功能,还请指教!
测试源码下载地址:http://download.csdn.net/detail/liuxian13183/5088495