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);
保存图片的时候调整角度:
效果图如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
android 实现自动拍照,Android自定义相机实现定时拍照功能相关推荐
- Android自定义相机实现定时拍照
这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能. 首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件: activity_main.xml <F ...
- android 自定义相机,Android自定义相机实现定时拍照功能
这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能. 首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件: activity_main.xml andro ...
- Android开发(Jetpack) 学习CameraX 自定义相机实现
目录 一.CameraX和Camera2 二.CameraX的引入 三.自定义拍照 四.自定义视频录制 五.XML 配置 一.CameraX和Camera2 CameraX 是一个 Jetpack 库 ...
- android文字自动滚动,Android TextView文字横向自动滚动(跑马灯)
TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true" 2.设置可滚到,或显示样式:android:elli ...
- android notification自动消失,Android开发 -- 状态栏通知Notification、NotificationManager详解...
本想自己写一个的,但是看到这篇之后,我想还是转过来吧,实在是非常的详细: 在Android系统中,发一个状态栏通知还是很方便的.下面我们就来看一下,怎么发送状态栏通知,状态栏通知又有哪些参数可以设置? ...
- android 导航自动切换,Android导航抽屉切换图标向右
吃鸡游戏 我为EndDrawerToggle该类编写了一个与您的设置非常相似的设置- DrawerLayout带末端对齐的抽屉View,AppCompatActivity带有自定义Toolbar的支持 ...
- android设置自动亮度,Android亮度调节的几种实现方法
最近在做一个App的设置项,亮度调节.真正做时,发现Android亮度调节比预想要复杂一些.其实目前网上已有不少这方面的资料,但有些博文具有一定误导性.在此将这块内容按照自己理解整理一下. 整体上看, ...
- android 键盘 自动消失,android 键盘状态,获取键盘显示和隐藏
要设置弹出键盘是否覆盖Activity的view,或者软键盘的显示隐藏状态,需要用到Activity的一个属性: android:windowSoftInputMode 该属性在AndroidMani ...
- android edittext自动获取焦点,Android取消EditText自动获取默认焦点
Android取消EditText自动获取默认焦点 发布时间:2020-10-02 14:08:30 来源:脚本之家 阅读:142 作者:ganchuanpu 最近在通讯录新建联系人=中,一进入一个页 ...
最新文章
- 关于S/4HANA里Sales Office 和Sales Organization那些事儿
- 20 道 Spring Boot 面试题
- 了解vue里的Runtime Only和Runtime+Compiler
- php多进程实现 亲测
- 【转】mac os、linux及unix之间的关系
- spring boot 异常汇总
- inotify监听文件夹的变动
- 201621123058《java程序设计》第二周学习总结
- 搭建卷积神经网络时loss计算方式的选择
- “约见”面试官系列之常见面试题第五篇说说vuex登录信息(建议收藏)
- 今天的一下子跳出来了的超级玛丽
- unity3d android debug log,调试 – 如何在连接到设备时看到MonoDevelop Unity中的Debug.Log输出?...
- 【BZOJ】【3671】【NOI2014】随机数生成器
- python引用参数在哪里_参数在Python中是否通过引用传递
- Spring Security三种认证
- 当我们点击一个文本域在IE下会发生的事件
- 《安富莱嵌入式周报》第259期:2022.03.28--2022.04.03
- 1.5时钟控制的触发器(钟控JK、钟控T触发器)
- Packet Tracer 思科模拟器入门教程 之十一 路由器静态路由配置
- 穆迪分析宣布推出云服务,助力银行实现监管合规