標籤:
由於我剛入職現在的這家公司的時候,他們對涉及到圖片的比較多,所以打算寫一系列圖片的文章,首先就從製造圖片的地方開始寫起–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實現的步驟了,當然還有增加許可權
<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();
下篇開始研究圖片了,這篇就先到這!
android 之 Camera