可以实现调用摄像头拍照,后台自动保存照片。
例子非常详细,经过测试后的。
关于评论中很多童鞋说不能连拍,在这里澄清一下:连拍功能在这里确实没有体现,我只是贴出了部分代码,实现了不阻塞主线程,且拍照完成后继续停留在拍摄界面,如果大家想要实现连拍,可以在onClick()方法中循环调用takePicture()方法,想要连拍几张自己定义,代码是用来学习的,希望大家可以体谅。
public class SnapPicActivity extends Activity
implements SurfaceHolder.Callback{
final private static String STILL_IMAGE_FILE = "capture.jpg";
final private static int IMAGE_NUM= 3;
private String strCaptureFilePath = "/sdcard/camera_snap.jpg";
private String TAG = "IsiCamera2Activity";
private Button btn_capture;
private Button btn_sum;
private Camera camera = null;
private SurfaceHolder mSurfaceHolder;
private SurfaceView mSurfaceView01;
private FrameLayout mFrameLayout01;
private boolean bPreviewing =false;
private int intScreenWidth;
private int intScreenHeight;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* 使应用程序全屏幕运行,不使用title bar */
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
/* 取得屏幕解析像素 */
getDisplayMetrics();
findViews();
getSurfaceHolder();
btn_capture.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
jumpOutAToast("test onclick");
//这里实现模拟连拍逻辑
for(int i=0; i<IMAGE_NUM; i++){
takeAPicture();
}
}
});
}
@Override
protected void onPause() {
//被交换到后台时执行
//camera.release();
//camera = null;
bPreviewing = false;
jumpOutAToast("test onPause");
super.onPause();
}
@Override
public void onStop() {
jumpOutAToast("test onStop");
resetCamera();
super.onStop();
}
@Override
protected void onResume() {
try {
initCamera();
} catch(IOException e ) {
Log.e(TAG,"initCamera() in Resume() erorr!");
}
jumpOutAToast("test onResume");
super.onResume();
}
/* function:
* 非preview时:实例化Camera,开始preview
* 非preview时and相机打开时:再设置一次preview
* preview时:不动作
*/
private void initCamera() throws IOException
{
if(!bPreviewing)
{
/* 若相机非在预览模式,则打开相机 */
camera = Camera.open();
camera.setDisplayOrientation(90);
}
//非预览时and相机打开时,开启preview
if (camera != null && !bPreviewing)
{
Log.i(TAG, "inside the camera");
/* 创建Camera.Parameters对象 */
Camera.Parameters parameters = camera.getParameters();
/* 设置相片格式为JPEG */
parameters.setPictureFormat(PixelFormat.JPEG);
/* 指定preview的屏幕大小 */
parameters.setPreviewSize(intScreenWidth, intScreenHeight);
/* 设置图片分辨率大小 */
parameters.setPictureSize(intScreenWidth, intScreenHeight);
/* 将Camera.Parameters设置予Camera */
camera.setParameters(parameters);
/* setPreviewDisplay唯一的参数为SurfaceHolder */
camera.setPreviewDisplay(mSurfaceHolder);
/* 立即运行Preview */
camera.startPreview();
bPreviewing = true;
}
}
/* func:停止preview,释放Camera对象*/
private void resetCamera()
{
if (camera != null && bPreviewing)
{
camera.stopPreview();
/* 释放Camera对象 */
camera.release();
camera = null;
bPreviewing = false;
}
}
/* func:停止preview*/
private void stopPreview() {
if (camera != null && bPreviewing) {
Log.v(TAG, "stopPreview");
camera.stopPreview();
}
}
private void takeAPicture() {
if (camera != null && bPreviewing)
{
/* 调用takePicture()方法拍照 */
camera.takePicture
(shutterCallback, rawCallback, jpegCallback);//调用PictureCallback interface的对象作为参数
}
}
/*func:获取屏幕分辨率*/
private void getDisplayMetrics() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
intScreenWidth = dm.widthPixels;
intScreenHeight = dm.heightPixels;
Log.i(TAG, Integer.toString(intScreenWidth));
}
private ShutterCallback shutterCallback = new ShutterCallback()
{
public void onShutter()
{
// Shutter has closed
}
};
private PictureCallback rawCallback = new PictureCallback()
{
public void onPictureTaken(byte[] _data, Camera _camera)
{
// TODO Handle RAW image data
}
};
private PictureCallback jpegCallback = new PictureCallback()
{
public void onPictureTaken(byte[] _data, Camera _camera)
{
//保存
Bitmap bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
if(bitmap!=null){
File myCaptureFile=new File(f"/sdcard/test.jpg");
BufferedOutputStream bos=null;
try {
bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bitmap.compress(CompressFormat.JPEG, mPicQuality, bos);
bos.close();
bitmap.recycle();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
resetCamera();
try {
initCamera();
} catch(Exception e) {
Log.e(TAG, "initCamera Error after snapping");
}
}
};
/* get a fully initialized SurfaceHolder*/
private void getSurfaceHolder() {
mSurfaceHolder = mSurfaceView01.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/* 把SurfaceView 加到FrameLayout 里*/
private void addSurfaceViewToFrameLayout() {
mFrameLayout01.addView(mSurfaceView01);
}
/*func:弹出toast,主要做测试用 */
private void jumpOutAToast(String string) {
Toast.makeText(IsiCamera2Activity.this, string,Toast.LENGTH_SHORT).show();
}
/* func:宣告界面元件Button capture,FrameLayout frame*/
private void findViews() {
btn_capture = (Button) findViewById(R.id.btn_capture);
btn_sum = (Button) findViewById(R.id.btn_sum);
/* 以SurfaceView作为相机Preview之用 */
mSurfaceView01 = (SurfaceView) findViewById(R.id.mSurfaceView01);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if(!bPreviewing) {
camera = Camera.open();
camera.setDisplayOrientation(90);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder,int format,int width,int height) {
if(bPreviewing) {
camera.stopPreview();
}
Camera.Parameters params = camera.getParameters();
params.setPreviewSize(width, height);
camera.setParameters(params);
try {
camera.setPreviewDisplay(mSurfaceHolder);
} catch(IOException e) {
e.printStackTrace();
}
camera.startPreview();
bPreviewing = true;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
bPreviewing = false;
camera.release();
mSurfaceHolder = null;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_capture"
android:layout_height="wrap_content"
android:text="@string/str_btn_capture"
android:layout_gravity="left" android:layout_width="148dp"/>
<Button
android:id="@+id/btn_sum"
android:layout_height="wrap_content"
android:text="@string/str_btn_closeAndSum"
android:layout_gravity="right" android:layout_width="154dp"/>
</LinearLayout>
<SurfaceView
android:id="@+id/mSurfaceView01"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.android.IsiCamera2"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<!-- 操作sd卡的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 打开操作拍照的权限 包括摄像头、操作SD卡、自动聚焦 -->
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-feature android:name="android.hardware.camera" />
<application android:label="@string/app_name" android:icon="@drawable/isilogo">
<activity android:name=".IsiCamera2Activity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>