Android开发:定制自己的Camera

移动开发 Android
Android自带的Camera应用虽然可以满足大多数情景,但是其灵活性上还有不足。但是Android允许我们定制自己的Camera。 本文介绍了如何定制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" />  
  • 1.
  • 2.
  • 3.

等。

本文实例:

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() { 
             
            @Override 
            public void onClick(View v) { 
                 
                camera.takePicture(nullnullnull, MyCamera.this); 
                 
            } 
        }); 
        //SurfaceView中的getHolder方法可以获取到一个SurfaceHolder实例 
        SurfaceHolder holder = surfaceView.getHolder(); 
        //为了实现照片预览功能,需要将SurfaceHolder的类型设置为PUSH 
        //这样,画图缓存就由Camera类来管理,画图缓存是独立于Surface的 
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
        holder.addCallback(this); 
    } 
    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    } 
    @Override 
    public 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(); 
         
    } 
    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
        // 当Surface被销毁的时候,该方法被调用 
        //在这里需要释放Camera资源 
        camera.stopPreview(); 
        camera.release(); 
         
    } 
    @Override 
    public 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 exception 
            e.printStackTrace(); 
        } 
         
        camera.startPreview(); 
    } 
     

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
责任编辑:徐川 来源: OSChina
相关推荐

2014-08-12 09:54:05

Android定制化启动器

2024-03-15 08:00:00

2024-09-14 14:09:40

2024-08-22 13:40:08

开发者GPT-4oepoch

2022-08-21 14:05:54

调试工具CDP

2021-09-02 07:04:45

Docker镜像语言

2024-03-29 15:43:32

大型语言模型人工智能

2014-05-22 14:15:45

Android系统定制小技巧

2009-10-10 16:31:13

VB开发定制控件

2014-03-13 09:46:36

Linux操作系统开源

2011-04-02 11:46:50

UI嵌入式开发

2011-07-25 09:24:07

2014-08-26 10:05:37

框架开发AngularJS

2023-11-26 00:17:21

2023-02-13 15:54:49

2016-03-02 10:27:16

Python定制化Eclipse IDE

2013-01-09 17:22:38

Android开发Camera

2017-03-08 17:47:50

数据

2012-04-26 22:32:01

Android

2019-04-04 14:23:08

GTK2GTK3Linux
点赞
收藏

51CTO技术栈公众号