android 之 Camera

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

下篇开始研究图片了,这篇就先到这!

时间: 2024-11-08 04:44:42

android 之 Camera的相关文章

android.hardware.Camera类及其标准接口介绍

android.hardware.Camera类及其标准接口介绍,API level 19 http://developer.android.com/reference/android/hardware/Camera.html

Android调用camera错误setParameters failed深层解析

1. Camera Camera是Android framework里面支持的,允许你拍照和拍摄视频的设备,那么,在使用camera开发中总是会遇到一些问题,例如以下这样子的: E/AndroidRuntime(1542): java.lang.RuntimeException: setParameters failed E/AndroidRuntime(1542):  at android.hardware.Camera.native_setParameters(Native Method)

【Android】Camera 使用浅析

Camera的简单使用浅析 由于最近工作上用到android.hardware.Camera这个类,于是简单的学习了一些基本用法. 首先注意:Camera这个类在API21以后就不推荐使用了,官方提供了一个新的类名叫:Camera2,其中包含了新的回调机制,感兴趣的朋友可以仔细研究研究. Camera官方API Guide:无墙又懒得打开本地doc的朋友请戳: http://www.android-doc.com/guide/topics/media/camera.html 其中描述了使用Cam

Android手势识别 Camera 预览界面上显示文字 布局注意事项(merge布局)

通常在Surfaceview作为预览视频帧的载体,有时需在上面显示提示文字.以前我弄的都好好的,今天忽然发现叠加的TextView不管咋弄都出不来文字了,跟Surfaceview一起放在FrameLayout也不行,后来想到merge布局,发现也不行.大爷的,奇了怪了,最后发现了原因,原来是顺序问题.也即无论是在RelativeLayout里还是merge布局里,View是逐个叠加上去的,一层一层铺上去的.如果你先放TextView在最前面,那肯定被后面的全屏Surfaceview覆盖了.用常规

[Android-Camera] If there is no flash setting option in Android stock camera apk, find the code and change it.

On freescale imx6 android platform, when we work on the Android stock camera apk, it's found that no flash setting option within it. So I track the code, and found that, flash avaliable need to be change from default value 0 to 1, it works. hardware\

Android 上Camera分析

http://blog.csdn.net/u010503912/article/details/52315721 一.Camera构架分析Android 的Camera包含取景(preview)和拍摄照片(take picture)的功能.目前Android发布版的Camera程序虽然功能比较简单,但是其程序的架构分成客户端和服务器两个部分,它们建立在 Android的进程间通讯Binder的结构上.Android中Camera模块同样遵循Andorid的框架,如下图所示 Camera Arch

Android自定义Camera

Build A CAMERA(创建一个自定义的Camera) 一些开发人员需要一个(为应用程序定制或提供特殊功能)的相机用户界面(自定义相机).创建一个定制的相机活动需要更多的代码,但它可以为你的用户提供更令人信服的体验. 为您的应用程序创建自定义相机接口的一般步骤如下: 1.        检测和访问摄像机-创建代码,以检查是否存在摄像头和允许访问. 2.        创建一个预览类,创建一个摄像机预览类继承SurfaceView实现SurfaceHolder接口.这类用于相机预览. 3. 

android通过camera和surfaceview选择摄像头并即时预览

在使用android设备的摄像头的时候我们有两种选择: 1.调用intent方法使用摄像头 2.通过camera类使用摄像头 第一种方法非常方便,不过需要跳到新的activity中,这样的用户体验并不是特别好 使用camera能有更大的自定义空间! 使用camera就需要用surfaceview显示摄像头的即时画面 我们这样设置layout: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu

Android 自定义Camera 随笔

  一.权限 <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" android:requ