Android自带的Camera应用虽然可以满足大多数情景,但是其灵活性上还有不足。但是Android允许我们定制自己的Camera。

在Android的hardware包中有一个Camera类。这个类就是获取Camera服务的,可以定制Camera等。

可以通过open()方法获取其实例。

在使用这个类是需要在AndroidManifest.xml文件中加入相应的权限和特性

如:

<uses-permission android:name = "android.permission.CAMERA" />
<uses-feature android:name = "android.hardware.camera" />
<uses-feature android:name = "android.hardware.camera.autofocus" />


等。

本文实例:

package demo.camera;import java.io.OutputStream;import java.util.Iterator;import java.util.List;import android.app.Activity;import android.content.ContentValues;import android.content.res.Configuration;import android.hardware.Camera;import android.net.Uri;import android.os.Bundle;import android.provider.MediaStore;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.widget.LinearLayout;/** * Android自带的Camera应用程序可以完成很多功能。但是当其不能满足我们需要的时候 * 我们可以定制自己的Camera。Android提供了Camera类来辅助我们实现自己的Camera。 * 这个例子就来定义一个自己的Camera * 首先,在Manifest中需要引入权限<uses-permission android:name="android:permission.CAMERA"/> * 我们需要用来存放取景器的容器,这个容器就是SurfaceView。 * 使用SurfaceView的同时,我们还需要使用到SurfaceHolder,SurfaceHolder相当于一个监听器,可以监听 * Surface上的变化,通过其内部类CallBack来实现。 * 为了可以获取图片,我们需要使用Camera的takePicture方法同时我们需要实现Camera.PictureCallBack类,实现onPictureTaken方法 * @author Administrator * */public class MyCamera extends Activity implements SurfaceHolder.Callback,Camera.PictureCallback{public static final int MAX_WIDTH = 200;public static final int MAX_HEIGHT = 200;private SurfaceView surfaceView;private Camera camera; //这个是hardare的Camera对象public void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);this.setContentView(R.layout.camera);surfaceView = (SurfaceView)this.findViewById(R.id.myCameraView);surfaceView.setFocusable(true); surfaceView.setFocusableInTouchMode(true);surfaceView.setClickable(true);surfaceView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {camera.takePicture(null, null, null, MyCamera.this);}});//SurfaceView中的getHolder方法可以获取到一个SurfaceHolder实例SurfaceHolder holder = surfaceView.getHolder();//为了实现照片预览功能,需要将SurfaceHolder的类型设置为PUSH//这样,画图缓存就由Camera类来管理,画图缓存是独立于Surface的holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);holder.addCallback(this);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// 当Surface被创建的时候,该方法被调用,可以在这里实例化Camera对象//同时可以对Camera进行定制camera = Camera.open(); //获取Camera实例/** * Camera对象中含有一个内部类Camera.Parameters.该类可以对Camera的特性进行定制 * 在Parameters中设置完成后,需要调用Camera.setParameters()方法,相应的设置才会生效 * 由于不同的设备,Camera的特性是不同的,所以在设置时,需要首先判断设备对应的特性,再加以设置 * 比如在调用setEffects之前最好先调用getSupportedColorEffects。如果设备不支持颜色特性,那么该方法将 * 返回一个null */try {Camera.Parameters param = camera.getParameters();if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){//如果是竖屏param.set("orientation", "portrait");//在2.2以上可以使用//camera.setDisplayOrientation(90);}else{param.set("orientation", "landscape");//在2.2以上可以使用//camera.setDisplayOrientation(0);}//首先获取系统设备支持的所有颜色特效,有复合我们的,则设置;否则不设置List<String> colorEffects = param.getSupportedColorEffects();Iterator<String> colorItor = colorEffects.iterator();while(colorItor.hasNext()){String currColor = colorItor.next();if(currColor.equals(Camera.Parameters.EFFECT_SOLARIZE)){param.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);break;}}//设置完成需要再次调用setParameter方法才能生效camera.setParameters(param);camera.setPreviewDisplay(holder);/** * 在显示了预览后,我们有时候希望限制预览的Size * 我们并不是自己指定一个SIze而是指定一个Size,然后 * 获取系统支持的SIZE,然后选择一个比指定SIZE小且最接近所指定SIZE的一个 * Camera.Size对象就是该SIZE。 *  */int bestWidth = 0;int bestHeight = 0;List<Camera.Size> sizeList = param.getSupportedPreviewSizes();//如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择if(sizeList.size() > 1){Iterator<Camera.Size> itor = sizeList.iterator();while(itor.hasNext()){Camera.Size cur = itor.next();if(cur.width > bestWidth && cur.height>bestHeight && cur.width <MAX_WIDTH && cur.height < MAX_HEIGHT){bestWidth = cur.width;bestHeight = cur.height;}}if(bestWidth != 0 && bestHeight != 0){param.setPreviewSize(bestWidth, bestHeight);//这里改变了SIze后,我们还要告诉SurfaceView,否则,Surface将不会改变大小,进入Camera的图像将质量很差surfaceView.setLayoutParams(new LinearLayout.LayoutParams(bestWidth, bestHeight));}}camera.setParameters(param);} catch (Exception e) {// 如果出现异常,则释放Camera对象camera.release();}//启动预览功能camera.startPreview();}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// 当Surface被销毁的时候,该方法被调用//在这里需要释放Camera资源camera.stopPreview();camera.release();}@Overridepublic void onPictureTaken(byte[] data, Camera camera) {// data是一个原始的JPEG图像数据,//在这里我们可以存储图片,很显然可以采用MediaStore//注意保存图片后,再次调用startPreview()回到预览Uri imageUri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());try {OutputStream os = this.getContentResolver().openOutputStream(imageUri);os.write(data);os.flush();os.close();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}camera.startPreview();}}


更多相关文章

  1. Android与JS之间的互相调用交互(一)
  2. Android下生成core dump的方法
  3. Android画图之抗锯齿
  4. 如何调用Android隐藏API
  5. Android(安卓)AsyncTask基础
  6. Android(安卓)C/C++ 开发.
  7. android permission权限与安全机制解析(下)
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. android 显示特殊符号
  2. Android多媒体开发高级编程
  3. Android(安卓)开发最佳实践
  4. AndroidStudio 3.0 加载Android(安卓)sup
  5. ProgressBar的简单使用
  6. android防止屏幕关闭后后台服务停止运行
  7. ANDROID应用程序的混淆打包
  8. 2011.09.26(2)——— android sample之Note
  9. android开机动画bootanimation
  10. Android(安卓)编程下 Touch 事件的分发和