现在的位置: 首页 > 综合 > 正文

Android中级第四讲–相机程序开发

2013年10月09日 ⁄ 综合 ⁄ 共 4875字 ⁄ 字号 评论关闭


博客出自: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


抱歉!评论已关闭.