編輯:關於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();
下篇開始研究圖片了,這篇就先到這!
[android] 手機衛士設置向導頁面,android向導設置向導頁面,通過SharedPreferences來判斷是否已經設置過了,跳轉到不同的頁面 自
我的android學習經歷13,android學習經歷13ToggleButton控件的使用 ToggleButton控件看名字就可以知道它是一個 “開關&r
圖片放大縮小(和ViewPager配合使用流暢顯示)--第三方開源--PhotoView, 圖片的放大縮小實現效果是使用的github上的一個開源項目photoView實
快速自動更新Android Studio版本 快速自動更新Android Studio版本 在開發過程中,有些時候總是會報一些Android Studio vesio
集成websocket即時通訊 java聊天源碼 代碼下載 java後台