Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 之 Camera

android 之 Camera

編輯:關於Android編程

由於我剛入職現在的這家公司的時候,他們對涉及到圖片的比較多,所以打算寫一系列圖片的文章,首先就從制造圖片的地方開始寫起–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

檢查Camera是否存在 初始化Camera 設置參數 預覽圖片 拍照 釋放Camera

這就是自定義Camera實現的步驟了,當然還有增加權限

只要把CameraView當成自定義控件使用就好

點擊拍照按鈕直接調用takePicture(),當然也可以自己定義圖片地址

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

還可以實現聚焦之後自動拍照

cameraView.autoFocus();

下篇開始研究圖片了,這篇就先到這!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved