欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义照相机倒计时拍照

程序员文章站 2023-12-17 08:47:22
自定义拍照会用到surfaceview控件显示照片的预览区域,以下是布局文件: 两个textview是用来显示提示信息和倒计时的秒数的 相关教程:android...

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

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

相关教程:android开发从相机或相册获取图片裁剪

android启动相机拍照并返回图片

<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;
 }
 }
 }

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

上一篇:

下一篇: