android 7自定义相机预览及拍照功能
作者:释汐宇辰 发布时间:2023-01-29 06:56:34
标签:android,相机预览,拍照
本文实例为大家分享了Android实现摄像头切换,拍照及保存到相册,预览等功能,解决android7拍照之后不能连续预览的问题、参数设置相关问题以及前后摄像头语言颠倒等问题。
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import com.hama.tracker.R;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class CamaraActivity extends Activity implements View.OnClickListener {
@Bind(R.id.return_back)
TextView returnBack;
@Bind(R.id.tvswitch_camera)
TextView tvswitchCamera;
//启动摄像机
private Camera mCamera;
public boolean isopen_camara = false;
private SurfaceView surfaceView;
private SurfaceHolder mholder = null;
private SurfaceCallback previewCallBack;
private boolean isTakingPhoto;//是否正在拍照
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
verifyPermission(new String[]{Manifest.permission.CAMERA});
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_camara);
ButterKnife.bind(this);
// 预览控件
surfaceView = (SurfaceView) this
.findViewById(R.id.surfaceView);
// 设置参数
surfaceView.getHolder().setKeepScreenOn(true);
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
returnBack.setOnClickListener(this);
tvswitchCamera.setOnClickListener(this);
EventBus.getDefault().register(this);
}
public void verifyPermission(String[] permissions) {
if (permissions != null) {
List<String> lists = new ArrayList<>();
for (int i = 0; i < permissions.length; i++) {
if (ActivityCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
}
lists.add(permissions[i]);
}
}
if (lists.size() > 0) {
String[] ps = new String[lists.size()];
for (int i = 0; i < lists.size(); i++) {
ps[i] = lists.get(i);
}
ActivityCompat.requestPermissions(this, ps, 1);
}
}
}
@Override
protected void onRestart() {
super.onRestart();
}
@Override
protected void onStart() {
super.onStart();
}
private void takePhoto() {
if (!isopen_camara) {
previewCallBack = new SurfaceCallback();
surfaceView.getHolder().addCallback(previewCallBack);
} else {
autoTakePhoto();
}
}
@Override
protected void onResume() {
super.onResume();
if(mCamera == null){
if (!isopen_camara) {
previewCallBack = new SurfaceCallback();
surfaceView.getHolder().addCallback(previewCallBack);
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.return_back:
finish();
break;
case R.id.tvswitch_camera:
switchCamara();
break;
}
}
// 预览界面回调
private final class SurfaceCallback implements SurfaceHolder.Callback {
// 预览界面被创建
public void surfaceCreated(SurfaceHolder holder) {
try {
//1代表打开后置摄像头,0代表打开前置摄像头.
mCamera = Camera.open(cameraPosition);// 打开摄像头
setParams(holder,cameraPosition);
} catch (Exception e) {
e.printStackTrace();
if (mCamera != null) {
mCamera.stopPreview();
mCamera.lock();
mCamera.release();
mCamera = null;
}
finish();
//Toast.makeText(getApplicationContext(), "该手机不支持自动拍照功能", Toast.LENGTH_LONG).show();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
System.out.println("surfaceChanged");
isopen_camara = true;
//autoTakePhoto();
}
// 预览界面被销毁
public void surfaceDestroyed(SurfaceHolder holder) {
System.out.println("surfaceDestroyed");
if(!isopen_camara)
return;
if (mCamera != null) {
holder.removeCallback(this);
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.lock();
mCamera.release();
mCamera = null;
}
}
}
public void reset(){
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
if (mCamera != null) {
if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){
surfaceView.getHolder().removeCallback(previewCallBack);
}
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.lock();
mCamera.release();
mCamera = null;
mCamera = Camera.open(cameraPosition);
if (null != mholder)
setParams(mholder,cameraInfo.facing);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mCamera != null) {
if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){
surfaceView.getHolder().removeCallback(previewCallBack);
}
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.lock();
mCamera.release();
mCamera = null;
}
ButterKnife.unbind(this);
EventBus.getDefault().unregister(this);
}
private void setParams(SurfaceHolder mySurfaceView,int postion) {
try {
int PreviewWidth = 0;
int PreviewHeight = 0;
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);//获取窗口的管理器
/*PreviewWidth = display.();
PreviewHeight = display.getHeight();*/
Camera.Parameters parameters = mCamera.getParameters();
// 选择合适的预览尺寸
List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
// 如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择
if (sizeList.size() > 1) {
Iterator<Camera.Size> itor = sizeList.iterator();
while (itor.hasNext()) {
Camera.Size cur = itor.next();
/*if (cur.width >= PreviewWidth
&& cur.height >= PreviewHeight) {*/
if (cur.width >= PreviewWidth
&& cur.height >= PreviewHeight) {
PreviewWidth = cur.width;
PreviewHeight = cur.height;
break;
}
}
}
parameters.setPreviewSize(PreviewWidth, PreviewHeight); //获得摄像区域的大小
//parameters.setPreviewFrameRate(3);//每秒3帧 每秒从摄像头里面获得3个画面
//parameters.setPreviewFpsRange(3,);
List<int[]> list = parameters.getSupportedPreviewFpsRange();
int[] v = null;
int index = 0;
int min = 0;
for (int i = 0; i < list.size(); i++) {
v = list.get(i);
if (v[0] > min) {
min = v[0];
index = i;
}
}
parameters.setPreviewFpsRange(list.get(index)[0], list.get(index)[1]);
parameters.setPictureFormat(PixelFormat.JPEG);//设置照片输出的格式
parameters.set("jpeg-quality", 85);//设置照片质量
parameters.setPictureSize(PreviewWidth, PreviewHeight);//设置拍出来的屏幕大小
parameters.setRotation(180); //Java部分
if (Build.VERSION.SDK_INT >= 24) {
if(postion == 0){
mCamera.setDisplayOrientation(90);
}else {
mCamera.setDisplayOrientation(270);
}
} else {
mCamera.setDisplayOrientation(90);
}
mCamera.setParameters(parameters);//把上面的设置 赋给摄像头
mCamera.setPreviewDisplay(mySurfaceView);//把摄像头获得画面显示在SurfaceView控件里面
mholder = mySurfaceView;
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
}
});
mCamera.startPreview();//开始预览
// mPreviewRunning = true;
} catch (IOException e) {
Log.e("tag", e.toString());
}
}
Handler handler = null;
private void autoTakePhoto() {
// 拍照前需要对焦 获取清析的图片
if (null == mCamera) return;
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success && isopen_camara) {
// 对焦成功
// Toast.makeText(MainActivity.this, "对焦成功 !!",Toast.LENGTH_SHORT).show();
if(!isTakingPhoto) {
isTakingPhoto = true;
handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
mCamera.takePicture(null, null, new MyPictureCallback());
}
});
}
}
}
});
}
// 照片回调
private final class MyPictureCallback implements Camera.PictureCallback {
// 照片生成后
@Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
matrix.setRotate(270);
File jpgFile = new File(Environment.getExternalStorageDirectory() + "/DCIM/camera");
if (!jpgFile.exists()) {
jpgFile.mkdir();
}
File jpgFile1 = new File(jpgFile.getAbsoluteFile(), System.currentTimeMillis() + ".jpg");
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
FileOutputStream fos = new FileOutputStream(jpgFile1);
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
ToastUtils.show(getApplicationContext(), getString(R.string.save_success));
fos.close();
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(jpgFile1);
intent.setData(uri);
sendBroadcast(intent);
} catch (Exception e) {
e.printStackTrace();
}finally {
if(Build.VERSION.SDK_INT>=24){
reset();
}
isTakingPhoto = false;
}
}
}
private int cameraPosition = 1;//0代表前置摄像头,1代表后置摄像头
private void switchCamara() {
//切换前后摄像头
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
for (int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
if (cameraPosition == 1) {
//现在是后置,变更为前置
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置
if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){
surfaceView.getHolder().removeCallback(previewCallBack);
}
mCamera.setPreviewCallback(null);
mCamera.stopPreview();//停掉原来摄像头的预览
mCamera.lock();
mCamera.release();//释放资源
mCamera = null;//取消原来摄像头
mCamera = Camera.open(i);//打开当前选中的摄像头
/* try {
if (null != mholder)
mCamera.setPreviewDisplay(mholder);//通过surfaceview显示取景画面
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();//开始预览*/
if (null != mholder)
setParams(mholder,Camera.CameraInfo.CAMERA_FACING_BACK);
cameraPosition = 0;
break;
}
} else {
//现在是前置, 变更为后置
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位,CAMERA_FACING_FRONT前置 CAMERA_FACING_BACK后置
if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){
surfaceView.getHolder().removeCallback(previewCallBack);
}
mCamera.setPreviewCallback(null);
mCamera.stopPreview();//停掉原来摄像头的预览
mCamera.lock();
mCamera.release();//释放资源
mCamera = null;//取消原来摄像头
mCamera = Camera.open(i);//打开当前选中的摄像头
/*try {
if (null != mholder)
mCamera.setPreviewDisplay(mholder);//通过surfaceview显示取景画面
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();//开始预览*/
if (null != mholder)
setParams(mholder,Camera.CameraInfo.CAMERA_FACING_FRONT);
cameraPosition = 1;
break;
}
}
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {///音量减拍照
takePhoto();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
来源:https://blog.csdn.net/chengjiamei/article/details/54895723


猜你喜欢
- CAS原理在计算机科学中,比较和交换(Compare And Swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较
- 详解java中的PropertyChangeSupport与PropertyChangeListenerjava中的PropertyChan
- 本文实例为大家分享了Java实现邮件找回密码功能的具体代码,供大家参考,具体内容如下1、有个需求就是,忘记密码后通过邮箱找回。现在的系统在注
- 本文实例为大家分享了Android实现仿网易音乐唱片播放效果的具体代码,供大家参考,具体内容如下效果图: 在values中创建attrs.x
- 本文实例为大家分享了JavaSE实现猜拳游戏的具体代码,供大家参考,具体内容如下import java.util.Random;import
- 在有些时候,我们需要从数据库读取数据填充对象或从硬盘读取文件填充对象,但是这样做相对耗时。这时候我们就想到了对象的拷贝。本文即以实例形式解析
- 目录前言导入okhttp3方法简介两种版本超时设置用法总结前言okhttp是一个处理网络请求的开源项目,是安卓端最火热的轻量级框架,由移动支
- Java执行hadoop的基本操作实例代码向HDFS上传本地文件public static void uploadInputFile(Str
- 十年前,Java 还是计算机科学的入门课程中的必学语言。如果你想学其他语言,比如 C、Python、PHP,你就得专门选那个语言的课程,或者
- 集合>队列Queue>创建队列System.Collections.Queue类提供了四种重载构造函数。using System
- 实验环境hadoop版本:3.3.2jdk版本:1.8hadoop安装系统:ubuntu18.04编程环境:IDEA编程主机:windows
- 最近一段时间生产环境频繁出问题,每次都会生成一个hs_err_pid*.log文件,因为工作内容的原因,在此之前并没有了解过相关内容,趁此机
- Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册
- 最近的项目,做图片的另存为功能,需要把图片存成jpg,png,bmp。对于jpg和png来说相对简单,android提供了bitmap.co
- 问题描述我在接受 mq 消息的时候,需要做一个重试次数限制,如果超过 maxNum 就发邮件告警,不再重试。所以我需要对 consumer
- 本文通过实例来介绍如何使用commons-fileupload.jar,Apache的commons-fileupload.jar可方便的实
- 1.控制屏幕常亮首先导入模块import brightness from '@system.brightness';接下来在
- 关于java8 的stream排序用法这里不做多说,这里介绍下曾经在多字段排序时遇到过的一个坑。需求:需要根据id去分组,然后取出每组中行号
- 读取文件流时,经常会遇到乱码的现象,造成乱码的原因当然不可能是一个,这里主要介绍因为文件编码格式而导致的乱码的问题。首先,明确一点,文本文件
- Scala异常处理Scala是一种多范式的编程语言,支持面向对象和函数式编程。Scala也支持异常处理,即在程序运行过程中发生意外或错误时,