Android实现摄像头拍照功能
作者:Hoking 发布时间:2022-04-25 13:05:55
应用场景:
在Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用。
知识点介绍:
使用权限:调用手机自身设备功能(摄像头拍照功能),应该确保已经在AndroidManifest.xml中正确声明了对摄像头的使用及其它相关的feature。
<!--摄像头权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!--存储权限 SD卡读写权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--Camera Feature 声明对camera feature的使用 -->
<uses-feature android:name="android.hardware.camera" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<!--视频、录音权限 请求音频捕获权限 -->
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
Class类:
1、 SurfaceView
视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。
2、 SurfaceHolder
SurfaceHolder是控制surface的一个抽象接口,你可以通过SurfaceHolder来控制surface的尺寸和格式,或者修改surface的像素,监视surface的变化等等,SurfaceHolder是SurfaceView的典型接口。
3、 SurfaceHolder.Callback
用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时, 它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。设置Callback的方法是SurfaceHolder.addCallback。
使用方式:
第一步:新建一个Android项目CameraTest,包含两个Activity: MainActivity、CameraActivity。
第二步:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="#FFFFFF"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent">
<ImageView
android:id="@+id/main_image"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:layout_width="match_parent"/>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:orientation="horizontal">
<Button android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="@+id/main_camera"
android:text="拍照"/>
<Button android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="退出"
android:id="@+id/main_quit"/>
</LinearLayout>
</RelativeLayout>
MainActivity.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
private Button cameraButton; //拍照按钮
private Button quitButton; //退出按钮
private ImageView imageView; //图片显示
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
imageView = (ImageView) findViewById(R.id.main_image);
// 从本地取图片(在sdcard中获取文件)
Bitmap bitmap = getLoacalBitmap("/sdcard/mhc.jpg");
Log.e("msgTag", new File("/sdcard/mhc.jpg").exists()+"==========");
imageView .setImageBitmap(bitmap); //设置Bitmap
cameraButton = (Button) findViewById(R.id.main_camera);
quitButton = (Button) findViewById(R.id.main_quit);
MainOnClickListener mainOnClickListener = new MainOnClickListener();
cameraButton.setOnClickListener(mainOnClickListener);
quitButton.setOnClickListener(mainOnClickListener);
}
private class MainOnClickListener implements OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_camera:
startActivity(new Intent(MainActivity.this, CameraActivity.class));
break;
case R.id.main_quit:
MainActivity.this.finish();
break;
default:
break;
}
}
}
/**
* 根据文件路径获取所需要文件,并将该文件封装成Bitmap对象返回
* @param fileUrl
* @return
*/
public static Bitmap getLoacalBitmap(String fileUrl) {
try {
FileInputStream fis = new FileInputStream(fileUrl);
return BitmapFactory.decodeStream(fis); ///把流转化为Bitmap图片
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
activity_camera.xml
<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="#FFFFFF"
tools:context=".CameraActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|center_horizontal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/camera_save"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="拍照" />
</LinearLayout>
</RelativeLayout>
CameraActivity.java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class CameraActivity extends Activity {
private String tag ="CameraActivity";
private SurfaceView surfaceView;
//Surface的控制器
private SurfaceHolder surfaceHolder;
private Camera camera;
private Button saveButton;
//拍照的回调接口
private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
new SavePictureTask().execute(data);
camera.startPreview();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
initViews();
}
private void initViews() {
saveButton = (Button) findViewById(R.id.camera_save);
surfaceView = (SurfaceView) findViewById(R.id.camera_preview);
surfaceHolder = surfaceView.getHolder();
// 给SurfaceView当前的持有者 SurfaceHolder 一个回调对象。
//用户可以实现此接口接收surface变化的消息。当用在一个SurfaceView 中时,
//它只在SurfaceHolder.Callback.surfaceCreated()和SurfaceHolder.Callback.surfaceDestroyed()之间有效。
//设置Callback的方法是SurfaceHolder.addCallback.
//实现过程一般继承SurfaceView并实现SurfaceHolder.Callback接口
surfaceHolder.addCallback(surfaceCallback);
// 设置surface不需要自己的维护缓存区
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
saveButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
camera.takePicture(null, null, pictureCallback);
// Camera.takePicture(shutterCallback,rawCallback,pictureCallback );
// private ShutterCallback shutterCallback = new ShutterCallback(){
// public void onShutter(){
// /* 按快门瞬间会执行这里的代码 */
// }
// };
// private PictureCallback rawCallback = new PictureCallback(){
// public void onPictureTaken(byte[] _data, Camera _camera){
// /* 如需要处理 raw 则在这里 写代码 */
// }
// };
// //当拍照后 存储JPG文件到 sd卡
// PictureCallback pictureCallback=new PictureCallback(){
// public void onPictureTaken(byte[] data,Camera camera) {
// FileOutputStream outSteam=null;
// try{
// SimpleDateFormat format=new SimpleDateFormat("yyyyMMddHHmmss");
// String times=format.format((new Date()));
// outSteam=new FileOutputStream("/sdcard/"+times+"mhc.jpg");
// outSteam.write(data);
// outSteam.close();
// }catch(FileNotFoundException e){
// Log.d("Camera", "row");
// } catch (IOException e) {
// e.printStackTrace();
// }
// };
// };
}
});
}
//SurfaceView当前的持有者的回调接口的实现
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
Log.e(tag, "摄像头Open完成");
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
camera.release();
camera = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(ImageFormat.JPEG);
camera.setDisplayOrientation(0);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
};
class SavePictureTask extends AsyncTask<byte[], String, String> {
@Override
protected String doInBackground(byte[]... params) {
File picture = new File("/sdcard/mhc.jpg");
try {
FileOutputStream fos = new FileOutputStream(picture.getPath());
fos.write(params[0]);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.e(tag, "照片保存完成");
CameraActivity.this.finish();
return null;
}
}
}
下载地址:Android实现摄像头拍照功能
来源:https://blog.csdn.net/mahoking/article/details/28225907


猜你喜欢
- 本文实例为大家分享了convinientbanner顶部广告轮播控件的具体代码,供大家参考,具体内容如下gradle中添加compile &
- 1. 背景介绍java中的数组比c语言中的数组,多了两个很重要的功能当索引越界时, 会自动抛出ArrayIndexOutOfBoundsEx
- 本文实例讲述了Android中断线程的处理方法。分享给大家供大家参考。具体方法如下:我现在对一个用户注册的功能1.用ProgressDial
- springBoot所有依赖和配置文件都写好的情况下1、dao接口的实现方法package com.cy.pj.sys.dao;import
- /*** 目的:实现AVL* 利用数组对左右儿子简化代码,但是对脑力难度反而增大不少,只适合acm模板* 其实
- <FrameLayout &
- Service概念及用途:Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们
- 引言其实对于分库分表这块的场景,目前市场上有很多成熟的开源中间件,eg:MyCAT,Cobar,sharding-JDBC等。本文主要是介绍
- 看完我上一篇文章,「你都理解创建线程池的参数吗?」之后,当遇到这种问题,你觉得你完全能够唬住面试官了,50k轻松到手。殊不知,要是面试官此刻
- 本系列代码地址:https://github.com/JoJoTec/spring-cloud-parentOpenFeign 的由来和实现
- 使用WebSocketSharp自定义实现Web服务时,无法解析multipart/form-data请求的数据。通过查找资料,采用以下方式
- Quick Start在SpringBoot中使用log4j2日志框架,只需三步:引入依赖配置log文件获取Logger实例并输出日志引入依
- 三层架构将整个业务应用划分为:(1)界面UI层(2)业务逻辑层(3)数据访问层对于复杂的系统分层可以让结构更加清晰,模块更加独立,便于维护。
- 在EditText输入数字的时候,通常我们需要限制小数点前后位数。比如金额输入一般我们需要限制小数点后面最多2位。我们可以通过 TextWa
- 目录开启定时任务注解@EnableScheduling@Scheduled添加定时任务Cron表达式在线cron工具适应场景springBo
- 前言假如有人问你这么几个问题,看能不能答上来Mybatis Mapper 接口没有实现类,怎么实现的 * JDK * 为什么不能对类进
- 举个例子:我有如下的一个需求,当我想要取得用户信息的时候,会先从本地缓存中查找,找不到然后从分布式缓存中查找,最后找不到再从数据库中查询。但
- //方法一//须添加对System.Web的引用//using System.Web.Security;/// <summary>
- 简介因为目前做的项目查询提供的接口都使用GraphQL替代典型的REST API,所以有必要去对它进行了解和源码的阅读。本篇主要大致了解下G
- 本文实例为大家分享了C语言非递归后序遍历二叉树的具体代码,供大家参考,具体内容如下法一:实现思路:一个栈 先按 根->右子树->