Android TextureView实现Camera相机预览、拍照功能

embedded/2024/10/20 2:40:40/

说明:本文使用的是Camera,不是Camera2,CameraX。

1、首先AndroidManifest添加相机使用权限

<!-- 相机相关 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

使用的activity添加硬件加速(默认开启,为啥要开启可自行百度)

android:hardwareAccelerated="true"
2、创建继承于TextureView的类MyTextureView(添贴代码)
package com.nxm.textureviewdemo;import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.Camera;
import android.os.Build;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;/*** *************************************************************************************************** 修改日期                         修改人             任务名称                         功能或Bug描述* 2018/10/12 10:36                 MUZI102                                             TextureView类目* ***************************************************************************************************/
public class MyTextureView extends TextureView implements View.OnLayoutChangeListener {public Camera mCamera;private Context context;private Camera.Parameters param;private boolean isCanTakePicture = false;Matrix matrix;Camera camera;int mWidth = 0;int mHeight = 0;int mDisplayWidth = 0;int mDisplayHeight = 0;int mPreviewWidth = 640;int mPreviewHeight = 480;int orientation = 0;public MyTextureView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;init();}private void init() {if (null == mCamera) {mCamera = Camera.open();}this.setSurfaceTextureListener(new SurfaceTextureListener() {@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {param = mCamera.getParameters();param.setPictureFormat(PixelFormat.JPEG);param.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);if (!Build.MODEL.equals("KORIDY H30")) {param.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 1连续对焦} else {param.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);}mCamera.setParameters(param);//变形处理RectF previewRect = new RectF(0, 0, mWidth, mHeight);double aspect = (double) mPreviewWidth / mPreviewHeight;if (getResources().getConfiguration().orientation== Configuration.ORIENTATION_PORTRAIT) {aspect = 1 / aspect;}if (mWidth < (mHeight * aspect)) {mDisplayWidth = mWidth;mDisplayHeight = (int) (mHeight * aspect + .5);} else {mDisplayWidth = (int) (mWidth / aspect + .5);mDisplayHeight = mHeight;}RectF surfaceDimensions = new RectF(0, 0, mDisplayWidth, mDisplayHeight);Matrix matrix = new Matrix();matrix.setRectToRect(previewRect, surfaceDimensions, Matrix.ScaleToFit.FILL);MyTextureView.this.setTransform(matrix);//<-处理变形int displayRotation = 0;WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);int rotation = windowManager.getDefaultDisplay().getRotation();switch (rotation) {case Surface.ROTATION_0:displayRotation = 0;break;case Surface.ROTATION_90:displayRotation = 90;break;case Surface.ROTATION_180:displayRotation = 180;break;case Surface.ROTATION_270:displayRotation = 270;break;}Camera.CameraInfo info = new Camera.CameraInfo();Camera.getCameraInfo(0, info);int orientation;if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {orientation = (info.orientation - displayRotation + 360) % 360;} else {orientation = (info.orientation + displayRotation) % 360;orientation = (360 - orientation) % 360;}mCamera.setParameters(param);mCamera.setDisplayOrientation(orientation);try {mCamera.setPreviewTexture(surfaceTexture);mCamera.startPreview();isCanTakePicture = true;} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {if (mCamera != null) {mCamera.stopPreview();mCamera.release();mCamera = null;isCanTakePicture = true;}return true;}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}});}/*** 拍照*/public void take() {if (mCamera != null && isCanTakePicture) {isCanTakePicture = false;mCamera.takePicture(new Camera.ShutterCallback() {@Overridepublic void onShutter() {}}, null, mPictureCallback);}}public void startPreview() {if (mCamera != null && !isCanTakePicture) {MyTextureView.this.setBackgroundDrawable(null);mCamera.startPreview();isCanTakePicture = true;}}public void stopPreview() {if (mCamera != null) {mCamera.stopPreview();}}public void releaseTextureView(){if (mCamera != null) {mCamera.stopPreview();mCamera.release();mCamera = null;isCanTakePicture = true;}}Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {@Overridepublic void onPictureTaken(byte[] data, Camera camera) {if (mCamera != null) {mCamera.stopPreview();new FileSaver(data).save();}}};@Overridepublic void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {mWidth = right - left;mHeight = bottom - top;}private class FileSaver implements Runnable {private byte[] buffer;public FileSaver(byte[] buffer) {this.buffer = buffer;}public void save() {new Thread(this).start();}@Overridepublic void run() {try {File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),System.currentTimeMillis() + ".png");file.createNewFile();FileOutputStream os = new FileOutputStream(file);BufferedOutputStream bos = new BufferedOutputStream(os);Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);bos.flush();bos.close();os.close();MyTextureView.this.setBackgroundDrawable(new BitmapDrawable(bitmap));} catch (Exception e) {e.printStackTrace();}}}
}
3、acticity中使用

1、xml的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.nxm.textureviewdemo.MyTextureViewandroid:id="@+id/mytextureview"android:layout_width="match_parent"android:layout_height="match_parent" /><Buttonandroid:id="@+id/paizhai"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="拍照" /><Buttonandroid:id="@+id/yulan"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@id/paizhai"android:text="预览" /></RelativeLayout>

2、使用

package com.nxm.textureviewdemo;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;public class MainActivity extends AppCompatActivity {private MyTextureView myTextureView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myTextureView = findViewById(R.id.mytextureview);findViewById(R.id.paizhai).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {myTextureView.take();}});findViewById(R.id.yulan).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {myTextureView.startPreview();}});}@Overrideprotected void onStart() {super.onStart();myTextureView.startPreview();}@Overrideprotected void onStop() {myTextureView.stopPreview();super.onStop();}@Overrideprotected void onDestroy() {myTextureView.releaseTextureView();super.onDestroy();}
}

原文TextureView实现相机预览、拍照功能_textureview怎么设置图片-CSDN博客


http://www.ppmy.cn/embedded/128879.html

相关文章

云原生后端

云原生后端 云原生后端是当今软件开发领域的一个重要概念&#xff0c;它代表了将软件应用程序容器化部署在云环境中&#xff0c;并采用微服务架构进行开发和管理的一种趋势。这种趋势的兴起&#xff0c;得益于云计算和微服务架构的快速发展&#xff0c;以及企业对高效、灵活、…

OpenEuler操作系统 安装 部署 配置

目录 安装配置准备工作安装配置部署OpenEuler操作系统配置OpenEuler系统使用MoBaXterm连接关闭selinux&#xff0c; firewalld修改主机名修改root密码配置yum源查看网卡配置下载软件 网络配置nmtui——图形化界面配置nmclivim 修改系统文件 克隆虚拟机 安装配置 准备工作 进入…

如何测试IP速度?

了解代理的连接速度是否快速是确保网络使用效率和体验的关键因素之一。本文来为大家如何有效地评估和测试代理IP的连接速度&#xff0c;以及一些实用的方法和工具&#xff0c;帮助用户做出明智的选择和决策。 一、如何评估代理IP的连接速度 1. 使用在线速度测试工具 为了快速…

安装指定node.js 版本 精简版流程

首先 我们本机上是否安装有node 如果有 需要先卸载 卸载完成后 使用命令查看是否卸载干净 打开WinR 输入cmd 然后输入如下名: where node 如果没有目录显示 说明node 很干净 本机没有相关安装 在输入命令: where npm 如果有相关目录 需要删除掉 要不然 后续安装的…

基于CRNN模型的多位数字序列识别的应用【代码+数据集+python环境+GUI系统】

基于CRNN模型的多位数字序列识别的应用【代码数据集python环境GUI系统】 基于CRNN模型的多位数字序列识别的应用【代码数据集python环境GUI系统】 背景意义 多位手写数字识别&#xff0c;即计算机从纸张文档、照片、触摸屏等来源接收并解释可理解的手写数字输入的能力。 随着…

MySQL 9从入门到性能优化-二进制日志

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

关于武汉芯景科技有限公司的限流开关芯片XJ6241开发指南(兼容LTC4411)

一、芯片引脚介绍 1.芯片引脚 二、系统结构图 三、功能描述 1.CTL引脚控制VIN和VOUT的通断 2.CTL引脚控制STAT引脚的状态 3.输出电压高于输入电压加上–VRTO的值&#xff0c;芯片处于关断状态

联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键

联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键 文章目录 联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键1. 进入BIOS快捷键2. 快速进入BIOS设置界面3. 快速进入启动项选择界面 1. 进入BIOS快捷键 进入BIOS设置界面的快捷键为F2快速进入启动项选择界面的快捷键为F12 2. 快速进…