Android提供了Camera來控制拍照,步驟如下:
(1)調用Camera的open()方法打開相機。
(2)調用Camera的getParameters()獲取拍照參數,該方法返回一個Cmera.Parameters對象。
(3)調用Camera.Parameters對象對照相的參數進行設置。
(4)調用Camera的setParameters(),並將Camera.Parameters對象作爲參數傳入,這樣就可以對拍照進行參數控制,Android2.3.3以後不用設置。
(5)調用Camerade的startPreview()的方法開始預覽取景,在之前需要調用Camera的setPreviewDisplay(SurfaceHolder holder)設置使用哪個SurfaceView來顯示取得的圖片。
(6)調用Camera的takePicture()方法進行拍照。
(7)程序結束時,要調用Camera的stopPreview()方法停止預覽,並且通過Camera.release()來釋放資源。
需要賦予Camera的權限:
1 2 3 |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.CAMERA"/>
|
下面上代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
package com.lyj.camera;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView;
public class MyCameraActivity extends Activity implements SurfaceHolder.Callback {
private ImageView back, position;//返回和切換前後置攝像頭
private SurfaceView surface;
private ImageButton shutter;//快門
private SurfaceHolder holder;
private Camera camera;//聲明相機
private String filepath = "";//照片保存路徑
private int cameraPosition = 1;//0代表前置攝像頭,1代表後置攝像頭
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//沒有標題
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//設置全屏
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//拍照過程屏幕一直處於高亮
//設置手機屏幕朝向,一共有7種
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
//SCREEN_ORIENTATION_BEHIND: 繼承Activity堆棧中當前Activity下面的那個Activity的方向
//SCREEN_ORIENTATION_LANDSCAPE: 橫屏(風景照) ,顯示時寬度大於高度
//SCREEN_ORIENTATION_PORTRAIT: 豎屏 (肖像照) , 顯示時高度大於寬度
//SCREEN_ORIENTATION_SENSOR 由重力感應器來決定屏幕的朝向,它取決於用戶如何持有設備,當設備被旋轉時方向會隨之在橫屏與豎屏之間變化
//SCREEN_ORIENTATION_NOSENSOR: 忽略物理感應器——即顯示方向與物理感應器無關,不管用戶如何旋轉設備顯示方向都不會隨着改變("unspecified"設置除外)
//SCREEN_ORIENTATION_UNSPECIFIED: 未指定,此爲默認值,由Android系統自己選擇適當的方向,選擇策略視具體設備的配置情況而定,因此不同的設備會有不同的方向選擇
//SCREEN_ORIENTATION_USER: 用戶當前的首選方向
setContentView(R.layout.main);
back = (ImageView) findViewById(R.id.camera_back);
position = (ImageView) findViewById(R.id.camera_position);
surface = (SurfaceView) findViewById(R.id.camera_surface);
shutter = (ImageButton) findViewById(R.id.camera_shutter);
holder = surface.getHolder();//獲得句柄
holder.addCallback(this);//添加回調
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//surfaceview不維護自己的緩衝區,等待屏幕渲染引擎將內容推送到用戶面前
//設置監聽
back.setOnClickListener(listener);
position.setOnClickListener(listener);
shutter.setOnClickListener(listener);
}
//響應點擊事件
OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.camera_back:
//返回
MyCameraActivity.this.finish();
break;
case R.id.camera_position:
//切換前後攝像頭
int cameraCount = 0;
CameraInfo cameraInfo = new CameraInfo();
cameraCount = Camera.getNumberOfCameras();//得到攝像頭的個數
for(int i = 0; i < cameraCount; i ) {
Camera.getCameraInfo(i, cameraInfo);//得到每一個攝像頭的信息
if(cameraPosition == 1) {
//現在是後置,變更爲前置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表攝像頭的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK後置
camera.stopPreview();//停掉原來攝像頭的預覽
camera.release();//釋放資源
camera = null;//取消原來攝像頭
camera = Camera.open(i);//打開當前選中的攝像頭
try {
camera.setPreviewDisplay(holder);//通過surfaceview顯示取景畫面
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();//開始預覽
cameraPosition = 0;
break;
}
} else {
//現在是前置, 變更爲後置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表攝像頭的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK後置
camera.stopPreview();//停掉原來攝像頭的預覽
camera.release();//釋放資源
camera = null;//取消原來攝像頭
camera = Camera.open(i);//打開當前選中的攝像頭
try {
camera.setPreviewDisplay(holder);//通過surfaceview顯示取景畫面
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();//開始預覽
cameraPosition = 1;
break;
}
}
}
break;
case R.id.camera_shutter:
//快門
camera.autoFocus(new AutoFocusCallback() {//自動對焦
@Override
public void onAutoFocus(boolean success, Camera camera) {
// TODO Auto-generated method stub
if(success) {
//設置參數,並拍照
Parameters params = camera.getParameters();
params.setPictureFormat(PixelFormat.JPEG);//圖片格式
params.setPreviewSize(800, 480);//圖片大小
camera.setParameters(params);//將參數設置到我的camera
camera.takePicture(null, null, jpeg);//將拍攝到的照片給自定義的對象
}
}
});
break;
}
}
};
/*surfaceHolder他是系統提供的一個用來設置surfaceView的一個對象,而它通過surfaceView.getHolder()這個方法來獲得。
Camera提供一個setPreviewDisplay(SurfaceHolder)的方法來連接*/
//SurfaceHolder.Callback,這是個holder用來顯示surfaceView 數據的接口,他必須實現以下3個方法
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
//當surfaceview創建時開啓相機
if(camera == null) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);//通過surfaceview顯示取景畫面
camera.startPreview();//開始預覽
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
//當surfaceview關閉時,關閉預覽並釋放資源
camera.stopPreview();
camera.release();
camera = null;
holder = null;
surface = null;
}
//創建jpeg圖片回調數據對象
PictureCallback jpeg = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
//自定義文件保存路徑 以拍攝時間區分命名
filepath = "/sdcard/Messages/MyPictures/" new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) ".jpg";
File file = new File(filepath);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//將圖片壓縮的流裏面
bos.flush();// 刷新此緩衝區的輸出流
bos.close();// 關閉此輸出流並釋放與此流有關的所有系統資源
camera.stopPreview();//關閉預覽 處理數據
camera.startPreview();//數據處理完後繼續開始預覽
bitmap.recycle();//回收bitmap空間
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
|
聲明:eoe文章著作權屬於作者,受法律保護,轉載時請務必以超鏈接形式附帶如下信息
原文作者: lyj724929676