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;
}
}
}
希望大家理解核心代码的详细注释,欢迎提供意见,希望能给大家带来帮助,谢谢!
源码:http://pan.baidu.com/s/1kVSBEK3
Android—实现自定义相机倒计时拍照的更多相关文章
- 如何用uniapp+vue开发自定义相机插件——拍照+录像功能
调用手机的相机功能并实现拍照和录像是很多APP与插件都必不可少的一个功能,今天智密科技就来分享一下如何基于uniapp + vue实现自定义相机界面,并且实现: 1: 自定义拍照 2: 自定义录像 3 ...
- Android相机使用(系统相机、自定义相机、大图片处理)
本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理(避免OOM),还有简要提一下有些人Surf ...
- Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理 ...
- Android调用系统相机、自己定义相机、处理大图片
Android调用系统相机和自己定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,而且因为涉及到要把拍到的照片显示出来,该样例也会涉及到Android载入大图片时候的处 ...
- Android自定义相机拍照、图片裁剪的实现
最近项目里面又要加一个拍照搜题的功能,也就是用户对着不会做的题目拍一张照片,将照片的文字使用ocr识别出来,再调用题库搜索接口搜索出来展示给用户,类似于小猿搜题.学霸君等app. 其实Android提 ...
- Android Multimedia框架总结(十四)Camera框架初识及自定义相机案例
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52738492 前言:国庆节告一段 ...
- Android实现自定义的相机
使用系统相机 android中使用系统相机是很方便的,单这仅仅是简单的使用而已,并不能获得什么特殊的效果. 要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下 < ...
- Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能
Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...
- android 自定义相机
老规矩,先上一下项目地址:GitHub:https://github.com/xiangzhihong/CameraDemo 方式: 调用Camera API 自定义相机 调用系统相机 由于需求不同, ...
随机推荐
- 深入浏览器兼容 细数jQuery Hooks 属性篇
关于钩子:http://www.cnblogs.com/aaronjs/p/3387906.html 本章的目的很简单,通过钩子函数更细节的了解浏览器差异与处理方案, 版本是2.0.3所以不兼容ie6 ...
- Change Line Type in OpenCascade
Change Line Type in OpenCascade eryar@163.com 关键字KeyWords:OpenCascade,Line Aspect, Line Type 在OpenCa ...
- WPF调用Matlab函数方法
有的时候用C#写图像处理方法,比较费事,不如Matlab简单,但是Matlab又做不出WPF那样的好看界面,怎么办呢. 今天正好我要实现这个功能,就顺便写个小例子,给需要的人做个借鉴. 想要用WPF调 ...
- 前端学PHP之字符串函数
× 目录 [1]特点 [2]输出 [3]空格[4]大小写[5]HTML[6]格式化[7]比较 前面的话 字符串的处理和分析在任何编程语言中都是一个重要的基础,往往是简单而重要的.信息的分类.解析.存储 ...
- Snapshot Volume 操作 - 每天5分钟玩转 OpenStack(58)
Snapshot 可以为 volume 创建快照,快照中保存了 volume 当前的状态,以后可以通过 snapshot 回溯.snapshot 操作实现比较简单,流程图如下: 向 cinder-ap ...
- 重磅开源:TN文本分析语言
tn是desert(沙漠之鹰)和tan共同开发的一种用于匹配,转写和抽取文本的语言(DSL).并为其开发和优化了专用的编译器.基于递归下降方法和正则表达式,能解析自然文本并转换为树和字典,识别时间,地 ...
- spring源码分析之spring-core总结篇
1.spring-core概览 spring-core是spring框架的基石,它为spring框架提供了基础的支持. spring-core从源码上看,分为6个package,分别是asm,cgli ...
- 关于IE6的PNG图像透明使用AlphaImageLoader的缺点
PNG32的alpha透明效果在IE6下会出现bug,出现灰色背景.而目前的解决方案就是 IE提供的滤镜.需要注意的是滤镜并不是对原图片进行修改,而是对相应的html元素进行 修改.所以在一个html ...
- Masonry_设置比例
[self.bgView addSubview:self.progressImageView]; [self.progressImageView mas_makeConstraints:^(MASCo ...
- WebSocket 介绍(二)-WebSocket API
这一章介绍如何用WebSocket API来控制协议和创建应用,运用http://websocket.org 提供的现有WebSocket服务器,我们可以收发消息.创建一些简单的WebSocket应用 ...