zoukankan      html  css  js  c++  java
  • Android中级第四讲相机程序开发


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


  • 相关阅读:
    进程对象的属性或方法详解
    进程理论以及开启子进程的两种方式
    计算机发展史(多道技术)
    基于socketserver实现的并发(tcp和udp)
    基于udp协议的套接字及udp协议粘包问题
    模拟ssh的远程网络传输
    周考题目及答案
    c/s架构搭建
    网络编程基础
    10.16模拟赛(湖南集训)
  • 原文地址:https://www.cnblogs.com/fengju/p/6174472.html
Copyright © 2011-2022 走看看