android 之 Camera

来源:互联网 发布:cad是什么软件 编辑:程序博客网 时间:2024/06/07 20:01

由于我刚入职现在的这家公司的时候,他们对涉及到图片的比较多,所以打算写一系列图片的文章,首先就从制造图片的地方开始写起–Camera

如果你的app里面只是需要拍一张照片,只需要调用系统的照相机就可以满足你的需求了

通过ACTION_IMAGE_CAPTURE调用系统的照相机

intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);

然后在通过startActivityForResult方法跳转

onActivityResult:

Bundle extras = data.getExtras();Bitmap bitmap = (Bitmap) extras.get("data");showImage.setImageBitmap(bitmap);

一般的情况下这样就满足了你的需求,也不需要增加权限,但是这里需要注意的是通过data获得的是一张缩略图,如果想获得一张原图,就需要指定图片的保存地址

Uri  uri = Uri.fromFile(new File(path));   intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);           intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);

同样使用startActivityForResult方法跳转

onActivityResult:

FileInputStream fileInputStream = null;Bitmap output;try {     int degree = PhotoUtil.readPictureDegree(path);     fileInputStream = new FileInputStream(new File(path));     output = BitmapFactory.decodeStream(fileInputStream);                   
    showImage.setImageBitmap(PhotoUtil.rotaingImageView(degree,output));} catch (FileNotFoundException e) {     e.printStackTrace();}finally {     if (fileInputStream != null){     try {          fileInputStream.close();         } catch (IOException e) {               e.printStackTrace();         }     }}

其实拿到这个需要一下两句话就能拿到这个bitmap

fileInputStream = new FileInputStream(new File(path));output = BitmapFactory.decodeStream(fileInputStream);

但是保存在本地的图片,直接这样取得的照片旋转了90度,其中图片的旋转角度是记录在exif中的,所以为了把图片旋转过来,索性直接利用exif去取角度

/**     * 读取图片属性:旋转的角度     * @param path 图片绝对路径     * @return degree旋转的角度     */    public static int readPictureDegree(String path) {        int degree  = 0;        try {            ExifInterface exifInterface = new ExifInterface(path);            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);            switch (orientation) {                case ExifInterface.ORIENTATION_ROTATE_90:                    degree = 90;                    break;                case ExifInterface.ORIENTATION_ROTATE_180:                    degree = 180;                    break;                case ExifInterface.ORIENTATION_ROTATE_270:                    degree = 270;                    break;            }        } catch (IOException e) {            e.printStackTrace();        }        return degree;    }

然后根据取到的角度旋转bitmap

public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {        Matrix matrix = new Matrix();        matrix.postRotate(angle);        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);        return resizedBitmap;    }

对于图片的操作后面再说

这样就能实现获得原图,并且能够正向的显示图片,但是很多app不只是拍一张照片而已,所以下面开始介绍自定义Camera

package com.zimo.guo.customcamera.view;import android.content.Context;import android.content.pm.PackageManager;import android.graphics.ImageFormat;import android.hardware.Camera;import android.os.Environment;import android.util.AttributeSet;import android.view.SurfaceHolder;import android.view.SurfaceView;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;/** * Created by zimo on 15/12/27. */public class CameraView extends SurfaceView implements SurfaceHolder.Callback {    private Camera camera;    private SurfaceHolder holder;    private Context context;    private String picUrl;    public CameraView(Context context) {        super(context);        this.context = context;        initHolder();    }    public CameraView(Context context, AttributeSet attrs) {        super(context, attrs);        this.context = context;        initHolder();    }    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.context = context;        initHolder();    }    private void initHolder() {        holder = this.getHolder();        holder.addCallback(this);    }    private boolean existCamera(Context context) {        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);    }    /**     * 初始化相机     */    private void initCamera() {        if (camera == null) {            camera = Camera.open();        }    }    private void imagePreview(SurfaceHolder holder) {        try {            if (camera != null) {                camera.setPreviewDisplay(holder);                camera.setDisplayOrientation(90);                camera.startPreview();            }        } catch (IOException e) {            e.printStackTrace();        }    }    private void setParameters() {        if (camera != null) {            Camera.Parameters parameters = camera.getParameters();            parameters.setPictureFormat(ImageFormat.JPEG);//            parameters.setRotation(90);            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);            camera.setParameters(parameters);        }    }    private void releaseCamera() {        if (camera != null) {            camera.setPreviewCallback(null);            camera.stopPreview();            camera.release();            camera = null;        }    }    public void autoFocus(){        if (camera != null){            camera.autoFocus(new Camera.AutoFocusCallback() {                @Override                public void onAutoFocus(boolean success, Camera camera) {                    if (success){                        takePicture();                    }                }            });        }    }    public void takePicture(){        if (camera != null){            camera.takePicture(null, null, new Camera.PictureCallback() {                @Override                public void onPictureTaken(byte[] data, Camera camera) {                    if (picUrl == null) {                        picUrl = Environment.getExternalStorageDirectory() + File.separator + "zimo.jpg";                    }                    File file = new File(picUrl);                    if (file.exists()) {                        file.delete();                    }                    try {                        FileOutputStream fos = new FileOutputStream(file);                        fos.write(data);                        fos.close();                    } catch (FileNotFoundException e) {                        e.printStackTrace();                    } catch (IOException e) {                        e.printStackTrace();                    }                    imagePreview(holder);                }            });        }    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        if (existCamera(context)){            initCamera();        }    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {        setParameters();        imagePreview(holder);    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        releaseCamera();    }    public void setPicUrl(String picUrl) {        this.picUrl = picUrl;    }}

上面是一个自定义的Camera,继承了SurfaceView

  1. 检查Camera是否存在
  2. 初始化Camera
  3. 设置参数
  4. 预览图片
  5. 拍照
  6. 释放Camera

这就是自定义Camera实现的步骤了,当然还有增加权限

<uses-permission android:name="android.permission.CAMERA"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

只要把CameraView当成自定义控件使用就好

<com.zimo.guo.customcamera.view.CameraView        android:id="@+id/camera"        android:layout_width="match_parent"        android:layout_height="match_parent" />

点击拍照按钮直接调用takePicture(),当然也可以自己定义图片地址

cameraView.setPicUrl(path);cameraView.takePicture();

还可以实现聚焦之后自动拍照

cameraView.autoFocus();


0 0