当前位置: 移动技术网 > IT编程>移动开发>Android > Android自定义照相机倒计时拍照

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

网上如何赚钱,小车车辆违章查询,曾宝仪的老公是谁

自定义拍照会用到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;
 }
 }
 }

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网