android 实现自动拍照,Android自定义相机实现定时拍照功能

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

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

activity_main.xml

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/surface_view"

android:layout_width="match_parent"

android:layout_height="match_parent" />

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical" >

android:id="@+id/start"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true"

android:layout_alignParentBottom="true"

android:layout_marginBottom="10dp"

android:src="@drawable/capture"/>

android:id="@+id/count_down"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_gravity="center"

android:gravity="center"

android:textSize="80sp"/>

MainActivity.java

package com.jackie.timercamera;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Matrix;

import android.hardware.Camera;

import android.media.AudioManager;

import android.media.MediaPlayer;

import android.net.Uri;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.support.v7.app.AppCompatActivity;

import android.util.Log;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.widget.ImageView;

import android.widget.TextView;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,

View.OnClickListener, Camera.PictureCallback {

private SurfaceView mSurfaceView;

private ImageView mIvStart;

private TextView mTvCountDown;

private SurfaceHolder mHolder;

private Camera mCamera;

private Handler mHandler = new Handler();

private int mCurrentTimer = 10;

private boolean mIsSurfaceCreated = false;

private boolean mIsTimerRunning = false;

private static final int CAMERA_ID = 0; //后置摄像头

// private static final int CAMERA_ID = 1; //前置摄像头

private static final String TAG = MainActivity.class.getSimpleName();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

initEvent();

}

@Override

protected void onPause() {

super.onPause();

stopPreview();

}

private void initView() {

mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);

mIvStart = (ImageView) findViewById(R.id.start);

mTvCountDown = (TextView) findViewById(R.id.count_down);

}

private void initEvent() {

mHolder = mSurfaceView.getHolder();

mHolder.addCallback(this);

mIvStart.setOnClickListener(this);

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

mIsSurfaceCreated = true;

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

startPreview();

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

mIsSurfaceCreated = false;

}

private void startPreview() {

if (mCamera != null || !mIsSurfaceCreated) {

Log.d(TAG, "startPreview will return");

return;

}

mCamera = Camera.open(CAMERA_ID);

Camera.Parameters parameters = mCamera.getParameters();

int width = getResources().getDisplayMetrics().widthPixels;

int height = getResources().getDisplayMetrics().heightPixels;

Camera.Size size = getBestPreviewSize(width, height, parameters);

if (size != null) {

//设置预览分辨率

parameters.setPreviewSize(size.width, size.height);

//设置保存图片的大小

parameters.setPictureSize(size.width, size.height);

}

//自动对焦

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

parameters.setPreviewFrameRate(20);

//设置相机预览方向

mCamera.setDisplayOrientation(90);

mCamera.setParameters(parameters);

try {

mCamera.setPreviewDisplay(mHolder);

} catch (Exception e) {

Log.d(TAG, e.getMessage());

}

mCamera.startPreview();

}

private void stopPreview() {

//释放Camera对象

if (mCamera != null) {

try {

mCamera.setPreviewDisplay(null);

mCamera.stopPreview();

mCamera.release();

mCamera = null;

} catch (Exception e) {

Log.e(TAG, e.getMessage());

}

}

}

private Camera.Size getBestPreviewSize(int width, int height,

Camera.Parameters parameters) {

Camera.Size result = null;

for (Camera.Size size : parameters.getSupportedPreviewSizes()) {

if (size.width <= width && size.height <= height) {

if (result == null) {

result = size;

} else {

int resultArea = result.width * result.height;

int newArea = size.width * size.height;

if (newArea > resultArea) {

result = size;

}

}

}

}

return result;

}

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.start:

if (!mIsTimerRunning) {

mIsTimerRunning = true;

mHandler.post(timerRunnable);

}

break;

}

}

private Runnable timerRunnable = new Runnable() {

@Override

public void run() {

if (mCurrentTimer > 0) {

mTvCountDown.setText(mCurrentTimer + "");

mCurrentTimer--;

mHandler.postDelayed(timerRunnable, 1000);

} else {

mTvCountDown.setText("");

mCamera.takePicture(null, null, null, MainActivity.this);

playSound();

mIsTimerRunning = false;

mCurrentTimer = 10;

}

}

};

@Override

public void onPictureTaken(byte[] data, Camera camera) {

try {

FileOutputStream fos = new FileOutputStream(new File

(Environment.getExternalStorageDirectory() + File.separator +

System.currentTimeMillis() + ".png"));

//旋转角度,保证保存的图片方向是对的

Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

Matrix matrix = new Matrix();

matrix.setRotate(90);

bitmap = Bitmap.createBitmap(bitmap, 0, 0,

bitmap.getWidth(), bitmap.getHeight(), matrix, true);

bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

fos.flush();

fos.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

mCamera.startPreview();

}

/**

* 播放系统拍照声音

*/

public void playSound() {

MediaPlayer mediaPlayer = null;

AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

int volume = audioManager.getStreamVolume( AudioManager.STREAM_NOTIFICATION);

if (volume != 0) {

if (mediaPlayer == null)

mediaPlayer = MediaPlayer.create(this,

Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));

if (mediaPlayer != null) {

mediaPlayer.start();

}

}

}

}

有两点需要注意:对于Camera来说,默认是横屏的,所以预览的时候和图片保存的时候都是横屏的,需要调整角度。

设置相机预览方法:

//设置相机预览方向

mCamera.setDisplayOrientation(90);

保存图片的时候调整角度:

b2963f4aef1feff4274179d2850aefcd.png

效果图如下:

541932c75d71986581c68f09a33dfdb5.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344302.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android版本8.1.0和9的区别,安卓8.1和9.0的区别是什么

安卓8.1和9.0的主要差别是&#xff1a;流畅度、耗电量、功能等等方面的不同。在手机配置足够的情况下&#xff0c;9.0要比8.1更流畅和省电&#xff0c;它可以同时让后台保持更多APP&#xff0c;每个APP运行的时候更加流畅&#xff0c;其新的智能电量管理功能、暗黑模式让手机更…

看到一个沙粒世界:再一次你好世界

“看到一个沙粒中的世界”&#xff0c;我们很可能会看到最简单的“ Hello World”中的世界&#xff0c;所以我们开始吧&#xff0c;再一次向世界问好。 我猜所有的Java课程&#xff0c;教程都是从这个著名的Hello World程序开始的&#xff0c;这是我可以在没有IDE的帮助下编写…

moreunit_MoreUnit与MoreUnit

moreunit就在一年多以前&#xff0c;我写了一篇关于在Eclipse中使用JUnit的文章。 评论者之一推荐MoreUnit &#xff0c;以进一步提高测试效率。 尝试一下让我感到很高兴&#xff0c;并且我的自主神经系统立即记住了该插件的键盘快捷键…… 另外&#xff0c;在使用MoreUnit一段…

JMetro版本5发布

Java的第5版JavaFX主题JMetro刚刚发布。 这是此版本中的新功能&#xff1a; 新的文本区域明暗风格&#xff1b; 现有控件样式的一些更改&#xff1b; 新CSS变量称为accent_color。 顾名思义&#xff0c;它允许您定义JMetro控件中使用的强调颜色。 已经进行了很大的重构&am…

android 开发 矩形截屏插件,Android 上如何实现矩形区域截屏

对屏幕进行截屏并裁剪有两种方式&#xff1a;早截图和晚截图。早截图&#xff0c;就是先截取全屏&#xff0c;再让用户对截取到的图片进行修改;与之相对的&#xff0c;晚截图&#xff0c;就是先让用户在屏幕上划好区域&#xff0c;再进行截图和裁剪。其实两者并没有什么太大的区…

Java可选参数

在Java类中设计方法时&#xff0c;某些参数对于其执行而言可能是可选的。 无论是在DTO&#xff0c;胖模型域对象还是简单的无状态服务类中&#xff0c;可选方法参数都是常见的。 从本文中&#xff0c; 您将学习如何在Java中处理可选参数 。 我们将专注于常规方法&#xff0c;带…

计算机发送到桌面快捷方式,windows7添加到桌面快捷方式无故消失!

您好&#xff0c;Windows 7设计者在Windows 7中所添加的设计。在默认情况下&#xff0c;只要System Maintenance troubleshooter(系统故障维护&#xff0c;以下简称SMT)检测到桌面的快捷方式已经无效了&#xff0c;将会自动将其删除。每周&#xff0c;SMT(系统故障维护)都会对操…

Java:汇总堆外数据

探索如何以最小的垃圾收集影响和最大的内存利用率创建堆​​外聚合。 使用Java Map&#xff0c;List和Object创建大型聚合通常会产生大量堆内存开销。 这也意味着&#xff0c;一旦聚合超出范围&#xff0c;垃圾收集器将必须清理这些对象。 阅读这篇简短的文章&#xff0c;了解…

java中属性外部化_用Java可外部化

java中属性外部化在理解Externalizable接口之前&#xff0c;您需要了解序列化。您可以在java中的序列化上阅读有关序列化的更多信息。 Java提供了一种称为序列化的机制&#xff0c;以按字节的有序或字节序列的形式持久化Java对象&#xff0c;其中包括对象的数据以及有关对象的…

在您的Maven-Fu包中增加了一些东西

Apache Maven很简单&#xff0c;但是功能非常强大。 使用一些技巧&#xff0c;您可以大大简化和优化您的开发经验。 处理多个非托管模块 假设您有一个主项目A提供了两个实用程序模块foo和bar &#xff0c;另一个项目B A了foo和bar 。 在使用B &#xff0c;您意识到需要偶尔对…

ci 邮件 html模板,CI Email类发邮件

发邮件代码详情private function _send_mail($data) {//附件一&#xff0c;名称参数编码转换if(!empty($data[resume_name])){$file_name iconv(UTF-8,GB2312,$data[file_name]);}//附件二&#xff0c;名称参数编码转换if(!empty($data[resume_name])){$resume_name iconv(UT…

Java安全动画

总览 自从JDK 1.2中引入安全沙箱模型以及JDK提供的安全API的发展以来&#xff0c;Java安全就一直是一个复杂的话题。 并发实用程序也观察到类似的问题&#xff0c;并且开发了一种名为Java Concurrent Animated的工具&#xff0c;目的是通过有趣而有趣的方式降低进入这些实用程序…

在计算机网络系统的远程通信中,在计算机网络系统的远程通信中,通常采用的传输技术是...

摘要&#xff1a;算机体系体系模板模板最适宜采用的合钢是组。系统信中民主命叙主义关于革命以下义革误的和社会主述错是(。程通常采传输不属民主主义济纲的三大经以下于新领的是(。...算机体系体系模板模板最适宜采用的合钢是组。网络不属特殊国无级自的是产阶以下于中有的优点…

ajax div 赋值重新渲染_优化向:单页应用多路由预渲染指南

前言Ajax 技术的出现&#xff0c;让我们的 Web 应用能够在不刷新的状态下显示不同页面的内容&#xff0c;这就是单页应用。在一个单页应用中&#xff0c;往往只有一个 html 文件&#xff0c;然后根据访问的 url 来匹配对应的路由脚本&#xff0c;动态地渲染页面内容。单页应用在…

fpga运算服务器_一张图了解CPU、GPU、ASIC、FPGA性能、功耗效率、灵活性

​CPU&#xff1a;中央处理器&#xff08;Central Processing Unit&#xff0c;CPU&#xff09;&#xff1a;通用芯片&#xff0c;主要生产厂家如intel、AMD等&#xff0c;用于PC、服务器等领域。CPU作为通用芯片&#xff0c;可以用来做很多事情&#xff0c;灵活性最高&#xf…

aspen变压吸附塔_空压机科普:吸附式干燥机的结构和原理

精彩内容本文以主流的“变压吸附式”干燥机为例进行讲解。“吸附”原理一致&#xff0c;“脱附再生”流程有所区别。从而大致形成以下几种常见类型&#xff1a;●无热吸附式——使用一部分经过干燥后的压缩空气&#xff0c;经降压后吹扫吸附剂&#xff0c;实现吸附剂“再生”&a…

小学计算机管理,小学计算机室管理制度

小学计算机室管理制度 (2页)本资源提供全文预览&#xff0c;点击全文预览即可全文预览,如果喜欢文档就下载吧&#xff0c;查找使用更方便哦&#xff01;19.90 积分芹菜小学计算机室制度1、计算机室由上电脑课老师负责管理。2、计算机室是进行电脑技术学习和操作的场所&#xff…

异形3×3魔方还原教程_【初级篇】(四)最简单的三阶魔方入门教程——中层还原...

本系列教程适合刚刚接触魔方&#xff0c;又比较有好奇心&#xff0c;是为渴望学会还原魔方&#xff0c;又不想死记公式的人准备的。全部教程只使用三种公式&#xff0c;还原过程以理解为主&#xff0c;公式为辅。第四部分 中层棱块还原4.1 预览中层棱块还原后的效果中层还原以后…

吞吐量-Corda的故事

我最近开展了一个针对特定用例的Corda性能项目。 这个项目的结果使我们在170多个节点的网络上一天之内处理了1.15亿个请求。 此外&#xff0c;Corda每秒能够处理6300个请求&#xff0c;确认满足了网络的最高要求。 迄今为止&#xff0c;这是迄今为止已部署的最大的Corda网络&am…

httpurlconnect设置中文参数_数控三菱CNC机床参数的设置及报警解除!

数控三菱CNC的硬件连接检查与设置执行完毕向系统送电后&#xff0c;显示器上的READY绿灯仍然不亮。而且在〔诊断〕――〔报警〕 画面上显示很多报警内容&#xff0c;哪些是开机时必须设置的呢&#xff1f;又如何解除故障报警呢&#xff1f;1.开机参数1.1 基本参数的设置原装系统…