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,一经查实,立即删除!

相关文章

10个步骤的筛选器模式

过滤器是仅在某些情况下应应用的模式。 在原始帖子中 &#xff0c;我提供了一个非常简单的示例&#xff0c;旨在演示如何应用它。 在这篇文章中&#xff0c;我提供了一个更详细的示例&#xff0c;该示例还旨在说明何时以及为什么应用它。 介绍 该职位包括以下10个简短步骤 。…

android 网络调试工具,安卓网络调试助手

安卓网络调试助手源码是一款专门为专业人士准备的安卓网络调试软件&#xff0c;安卓网络调试助手apk支持各种进制的转换发生和多种端口协议&#xff0c;让用户操作起来更加方便&#xff0c;安卓网络调试助手源码有着专业的操作流程&#xff0c;帮助用户快速上手&#xff0c;就算…

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的帮助下编写…

[渝粤教育] 西南科技大学 中国现代文学 在线考试复习资料

中国现代文学——在线考试复习资料 一、单选题 1.不属于“五四”时期的“问题小说”作家的是( )。 A.冰心 B.庐隐 C.刘呐鸥 D.王统照 2.巴金小说《家》中的觉新是( )。 A.顽固的封建卫道者 B.腐朽堕落者 C.有新思想的懦弱者 D.与封建思想大胆斗争的反抗者 3.《画梦录》的作者…

[渝粤教育] 西南科技大学 中学英语教材教法 在线考试复习资料

中学英语教材教法——在线考试复习资料 一、单选题 1.关于写作评估以下说法正确的是? A.写作评估既要有结果评估,也要有过程评估 B.写作教学评估有写长法又有写短法 C.课堂评估的作用仅为监控学生 D.课堂评估与课堂的具体教学内容有关,可以使用统一的评估模式 2.以下哪种方式…

moreunit_MoreUnit与MoreUnit

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

[渝粤教育] 西南科技大学 人力资源管理 在线考试复习资料(1)

人力资源管理——在线考试复习资料 一、单选题 1.实施工作轮换方案之前要做好的工作不包括( ) A.复查每一个连续在同一职业岗位上于了5年以上.特别是更长时间的、正处于职业中期的员工(包括经理在内) 的人事文件 B.评价这些员工的工作,认清其工作专长,了解其个人特征、才干等 C…

android 获取 meid 代码,Android 各个版本获取IMEI、MEID

public class IMEIUtil {/*** 获取默认的imei 一般都是IMEI 1** param context* return*/public static String getIMEI1(Context context) {//优先获取IMEI(即使是电信卡) 不行的话就获取MEIDreturn getImeiOrMeid(context, 0);}/*** 获取imei2** param context* return*/publ…

JMetro版本5发布

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

[渝粤教育] 西南科技大学 会计学原理 在线考试复习资料(1)

会计学原理——在线考试复习资料 一、单选题 1.资产负债表是反映企业( )财务状况的会计报表。 A.某一特定日期 B.一定时期内 C.某一月份内 D.某一年份内 2.某企业本期盘亏的材料已查明原因,属于自然损耗,批准处理时应编制的会计分录( )。 A.借记“待处理财产损溢”,…

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

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

[渝粤教育] 西南科技大学 供应链管理 在线考试复习资料

供应链管理——在线考试复习资料 一、单选题 1.人们设置库存的目的,不包括以下哪种? A.增加固定资产 B.防止缺货 C.保持生产连续性 D.快速满足订货需求 2.费希尔(Fisher)按市场需求模式将产品分为两类,即功能性产品和创新性产品。下面属于功能性产品的是: A.时装 B.石油 C.手…

[渝粤教育] 西南科技大学 信息组织与检索 在线考试复习资料2021版

信息组织与检索——在线考试复习资料2021版 一、单选题 1.要求两个关键词至少有一个出现在检索结果中需使用的操作符是( )。 A. ND B. OR C. ND NOT D. NEAR 答案:看左边查询 2.要求两个关键词都必须出现在检索结果中需使用的操作符是( )。 A. ND B. OR C. ND NOT D. NE…

Android布局怎么画图形,Android开发者的图形化布局

图形化布局编辑器允许你通过拖放来创建UI。在早期版本的ADT中&#xff0c;图形化布局编辑器并不是很有帮助&#xff0c;幸运的是&#xff0c;最新版本非常强大&#xff0c;可以用来创建复杂的包含有复合组件以及动画的布局。(1)Configuration下拉菜单让你可以改变当前布局展示的…

java注释类型_Java 8类型注释

java注释类型Lambda表达式是迄今为止Java 8讨论最多和最受促进的功能。虽然我同意Lambda是一个很大的改进&#xff0c;但我认为其他一些Java 8功能由于Lambda的炒作而有所欠缺。 在这篇文章中&#xff0c;我想展示另一个来自Java 8的出色特性的示例&#xff1a;Type Annotation…

[渝粤教育] 西南科技大学 公共组织学 在线考试复习资料

公共组织学——在线考试复习资料 一、单选题 1.从沟通媒介自身的丰富性程度看,排在第一位的应该是( ) A.电话 B.电子邮件 C.面对面地交谈 D.文件 2.“韦伯认为,以古老的传统、神圣不可侵犯的信念,以及对其下属行使权力的人的地位的合法性为基础的权力属于( ) A.合理–合法型…

[渝粤教育] 西南科技大学 刑事诉讼法学 在线考试复习资料

刑事诉讼法学——在线考试复习资料 一、单选题 1.传唤、拘传持续的时间不得超过十二小时;案情特别重大、复杂,需要采取拘留、逮捕措施的,传唤、拘传持续的时间不得超过( )小时。 A.12 B.24 C.48 2.无期徒刑的执行机关是?( ) A.公安机关 B.监狱 C.检察机关 D.人民法院 3.讯问…

android studio简易记账本,Android记账本

十分感谢徐老师用心制作的这个视频&#xff0c;我学到了很多&#xff0c;再次感谢。这里贴一下我对着这个视频写的代码&#xff1a;https://github.com/supertian007/ImoocDaily&#xff0c;欢迎大家参考、或指出问题。记录一下学习过程中遇到的几个问题&#xff1a;1. 视频的b…

Java可选参数

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