转载

Android—实现自定义相机倒计时拍照

这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能

首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件:

两个TextView是用来显示提示信息和倒计时的秒数的

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:background="#266194"     android:orientation="vertical"     tools:context=".TestActivity" >      <SurfaceView         android:id="@+id/surfaceView"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:layout_centerInParent="true" />      <LinearLayout         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_centerInParent="true"         android:orientation="vertical" >          <TextView             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:text="请调整位置到此区域"             android:textColor="#ff0000"             android:textSize="32sp" />          <TextView             android:id="@+id/tv_time"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:paddingTop="10dp"             android:gravity="center_horizontal"             android:textColor="#266194"             android:textSize="32sp" />     </LinearLayout>  </RelativeLayout> 

接下来是mainActivity中的具体实现以及详细注释:

 package com.dhsr.pujiejia.ui;  import java.io.File; import java.io.FileOutputStream; import java.text.SimpleDateFormat; import java.util.Date;  import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.PixelFormat; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Window; import android.view.WindowManager; import android.widget.TextView;  import com.example.pujiejiaapp.R;  @SuppressLint({ "NewApi", "SdCardPath" }) public class CameraActivity extends Activity implements Runnable {     // 预览图片范围     private SurfaceView surfaceView;     private TextView tv_time;     // 倒计时拍摄     private int cameratime = 4;     private Camera camera;     private boolean preview = false;     // 文件名字     private String filename;     // 文件名字的带的时间戳     private String timeString;     // 格式化时间     private SimpleDateFormat dateFormat;     // 日期对象     private Date date;     // 控制线程     boolean stopThread = false;     private File file;     String photo;      private Handler mHandler = new Handler() {         public void handleMessage(android.os.Message msg) {             int what = msg.what;             switch (what) {             case 222:                 tv_time.setText("" + cameratime);                 if ("0".equals(tv_time.getText().toString())) {                     tv_time.setText("拍摄成功!");                     takePhoto();                 }                 break;              }         };     };      @Override     protected void onCreate(Bundle savedInstanceState) {         // TODO Auto-generated method stub         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_test);         CameraActivity.this.setFinishOnTouchOutside(false);         // 初始化数据         findView();         surfaceView.getHolder().addCallback(new SufaceListener());         /* 下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前 */         surfaceView.getHolder()                 .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);         surfaceView.getHolder().setFixedSize(200, 200); // 设置分辨率     }      @Override     protected void onStart() {         // TODO Auto-generated method stub         super.onStart();         // 开启线程         new Thread(this).start();     }      private final class SufaceListener implements SurfaceHolder.Callback {         /**          * surface改变          */         @Override         public void surfaceChanged(SurfaceHolder holder, int format, int width,                 int height) {         }          /**          * surface创建          */         @Override         public void surfaceCreated(SurfaceHolder holder) {             try {                 for (int i = 0; i < Camera.getNumberOfCameras(); i++) {                     CameraInfo info = new CameraInfo();                     Camera.getCameraInfo(i, info);                     // 调用系统的前置摄像头                     if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {                         camera = Camera.open(i);                     }                 }                 Camera.Parameters parameters = camera.getParameters();                 /* 每秒从摄像头捕获5帧画面, */                 parameters.setPreviewFrameRate(5);                 /* 设置照片的输出格式:jpg */                 parameters.setPictureFormat(PixelFormat.JPEG);                 /* 照片质量 */                 parameters.set("jpeg-quality", 85);                 WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);                 camera.setParameters(parameters);                 camera.setPreviewDisplay(surfaceView.getHolder());// 通过SurfaceView显示取景画面                 camera.startPreview();                 preview = true;             } catch (Exception e) {              }         }          /**          * surface销毁          */         @Override         public void surfaceDestroyed(SurfaceHolder holder) {             if (camera != null) {                 if (preview)                     camera.stopPreview();                 camera.release();                 camera = null;             }         }     }      /**      * 拍摄照片      */     private void takePhoto() {         // 执行拍照效果         camera.takePicture(null, null, new Camera.PictureCallback() {             @Override             public void onPictureTaken(byte[] data, Camera camera) {                 try {                     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,                             data.length);                     timeString = formatDate();                     //保存到data/data目录自定义文件夹下                      filename = "/data/data/com.example.pujiejiaapp/images/"                      + timeString + ".jpg";                     File file = new File(filename);                     boolean createNewFile = file.createNewFile()                     System.out.println("创建文件夹成功没有" + createNewFile);                     System.out.println(file);                     FileOutputStream outStream = new FileOutputStream(file);                     bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);                     outStream.flush();                     outStream.close();                     // 重新浏览                     camera.stopPreview();                     camera.startPreview();                     preview = true;                 } catch (Exception e) {                     e.printStackTrace();                 } finally {                 }             }         });     }      @Override     public void run() {         while (!stopThread) {             try {                 //按秒数倒计时                 Thread.sleep(1000);             } catch (InterruptedException e) {                 // TODO Auto-generated catch block                 e.printStackTrace();             }             cameratime--;             mHandler.sendEmptyMessage(222);             if (cameratime <= 0) {                 break;             }         }     }      // 初始化数据     private void findView() {         surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);         tv_time = (TextView) findViewById(R.id.tv_time);     }      // 格式化系统的时间     public String formatDate() {         date = new Date(System.currentTimeMillis());         // 日期格式         dateFormat = new SimpleDateFormat("'IMG'_yyyyMMddHHmmss");         return dateFormat.format(date);     }      @Override     protected void onDestroy() {         // TODO Auto-generated method stub         // 线程已关闭         super.onDestroy();         stopThread = true;     }  } 

核心代码详解:

1.创建 SurfaceView时, surfaceCreated()方法中

for (int i = 0; i < Camera.getNumberOfCameras(); i++) {

CameraInfo info = new CameraInfo();

Camera.getCameraInfo(i, info);

// 调用系统的前置摄像头

if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {

camera = Camera.open(i);

}

}

此部分代码为打开相机时默认打开前置摄像头CameraInfo.CAMERA_FACING_BACK为默认打开后置摄像头,CameraInfo.CAMERA_FACING_FRONT前置摄像头

2.照片拍摄takePhoto()方法中:

Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,

data.length);

timeString = formatDate();

filename = "/data/data/com.example.pujiejiaapp/images/"

+ timeString + ".jpg";

photo = timeString + ".jpg";

File file = new File(filename);

boolean createNewFile = file.createNewFile();

FileOutputStream outStream = new FileOutputStream(file);

bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);

此部分代码为将拍摄到的图片保存为以bitmap格式保存在指定的目录下

3.开子线程用于倒计时拍摄

public void run() {

while (!stopThread) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

cameratime--;

mHandler.sendEmptyMessage(222);

if (cameratime <= 0) {

break;

}

}

}

希望大家理解核心代码的详细注释,欢迎提供意见,希望能给大家带来帮助,谢谢!

正文到此结束
Loading...