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

说明:本文使用的是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.rhkb.cn/news/450616.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FreeRTOS - 软件定时器

在学习FreeRTOS过程中&#xff0c;结合韦东山-FreeRTOS手册和视频、野火-FreeRTOS内核实现与应用开发、及网上查找的其他资源&#xff0c;整理了该篇文章。如有内容理解不正确之处&#xff0c;欢迎大家指出&#xff0c;共同进步。 1. 软件定时器 软件定时器也可以完成两类事情…

Spring AI Alibaba 接入国产大模型通义千问

整体介绍 本文是一个详细的例子&#xff0c;讲解了如何基于spring ai 来调用通义千问国产大模型&#xff0c;有详细的代码和配置&#xff0c;并且免费。 Spring AI&#xff1a;简化Java开发者构建AI应用的统一框架 在过去&#xff0c;Java 开发者在构建 AI 应用时面临的一大…

【ios】解决xcode版本过低无法真机调式的问题

最低要求和支持的 SDK&#xff1a;Xcode - 支持 - Apple Developer 我的Xcode版本是14.2 手机系统版本是iOS15.8.3 步骤一 在终端中运行 open /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport 步骤二 先去https://github.com/fi…

AI 设计工具合集

&#x1f423;个人主页 可惜已不在 &#x1f424;这篇在这个专栏AI_可惜已不在的博客-CSDN博客 &#x1f425;有用的话就留下一个三连吧&#x1f63c; ​ 前言: AI 视频&#xff0c;科技与艺术的精彩融合。它借助先进的人工智能技术&#xff0c;为影像创作带来全新可能。本书…

星海智算:【萤火遛AI-Stable-Diffusion】无需部署一键启动

部署流程 1、注册算力云平台&#xff1a;星海智算 https://gpu.spacehpc.com/ 2、创建实例&#xff0c;镜像请依次点击&#xff1a;“镜像市场”->“更换”->“AI绘画”->“萤火遛AI-Stable Diffusion”。 程序首次启动可能需要几分钟&#xff0c;待实例显示“运行…

2009年国赛高教杯数学建模A题制动器试验台的控制方法分析解题全过程文档及程序

2009年国赛高教杯数学建模 A题 制动器试验台的控制方法分析 汽车的行车制动器&#xff08;以下简称制动器&#xff09;联接在车轮上&#xff0c;它的作用是在行驶时使车辆减速或者停止。制动器的设计是车辆设计中最重要的环节之一&#xff0c;直接影响着人身和车辆的安全。为了…

MOE论文详解(4)-GLaM

2022年google在GShard之后发表另一篇跟MoE相关的paper, 论文名为GLaM (Generalist Language Model), 最大的GLaM模型有1.2 trillion参数, 比GPT-3大7倍, 但成本只有GPT-3的1/3, 同时效果也超过GPT-3. 以下是两者的对比: 跟之前模型对比如下, 跟GShard和Switch-C相比, GLaM是第一…

[WPF初学到大神] 1. 什么是WPF, MVVM框架, XAML?

什么是WPF? WPF(Windows Presentation Foundation) 包含XAML标记语言和后端代码来开发桌面应用程序的. 用VS新建项目有WPF(.Net Framework和.Net应用程序), 该怎么选? 首选 .NET 应用程序(.NET Core 或 .NET 5/6/7/8新版本)拥有更好的性能、跨平台Windows, Linux, Mac支…

电气自动化13:PLC控制硬件组成与工作扫描原理

1.PLC硬件组成&#xff1a; CPU&#xff08;中央处理器&#xff09; 存储器 系统程序存储器用户程序存储器分为&#xff1a;用户程序存储器&#xff08;程序区&#xff09;、功能存储器&#xff08;数据区&#xff09; 输入/输出&#xff08;I/O&#xff09;接口电路 电源 …

SpringBoot优雅下线

一&#xff0c;什么是优雅下线 当我们需要部署新版本代码的时候&#xff0c;需要重启服务&#xff0c;这个时候可能会出现一些问题&#xff0c;比如之前服务正在处理的请求还在处理&#xff0c;这个时候如果强制的停止服务&#xff0c;会造成数据丢失或者请求失败的情况。那么…

后端Web开发

一、Maven &#xff08;一&#xff09;、概述 视频中要用的是jdk11 &#xff08;二&#xff09;、 idea集成Maven 1.配置Maven环境 2.创建Maven项目 3.导入Maven项目 法一&#xff1a; 法二&#xff1a; &#xff08;三&#xff09;、依赖管理 1.依赖配置 2.依赖传递 3.依…

数控机械制造工厂ERP适用范围有哪些

在当今制造业高速发展的背景下&#xff0c;企业资源计划(ERP)系统已成为提升工厂管理效率、实现生产自动化与信息化的关键工具。特别是对于数控机械制造工厂而言&#xff0c;一个合适的ERP系统能够帮助其优化生产流程、提高产品质量、降低生产成本并增强市场竞争力。 1. 生产计…

06 算法基础:算法的定义、表现形式(自然语言、伪代码、流程图)、五个特性(有穷性、确定性、可行性、输入、输出)、好算法的设计目标

目录 1 算法的定义 2 算法的三种表现形式 2.1 自然语言 2.2 伪代码 2.3 流程图 3 算法的五个特性 3.1 有穷性 3.2 确定性 3.3 可行性 3.4 输入 3.5 输出 4 好算法的设计目标 4.1 正确性 4.2 可读性 4.3 健壮性 4.4 通用性 4.5 高效率与低存储量 1 算法的定义 …

Java笔记-static关键字

1.static关键字内存说明 2.访问特点 package com.test.Statics2;import com.test.statics.Student;public class Test {public static void main(String[] args) {// 静态成员中访问非静态成员// method3() // 错误-不能直接调用&#xff0c;需要new对象调用Test test01 new T…

英伟达开源超强模型Nemotron-70B;OpenAI推出Windows版ChatGPT桌面客户端

&#x1f989; AI新闻 &#x1f680; 英伟达开源超强模型Nemotron-70B 摘要&#xff1a;英伟达近日开源了新型AI模型Nemotron-70B&#xff0c;迅速超越GPT-4o和Claude 3.5 Sonnet&#xff0c;成为AI社区的新宠。该模型在多项基准测试中表现优异&#xff0c;采用混合训练方法和…

STM32CUBEIDE新建工程

新建工作区 可以在下面的目录创建工作区&#xff0c;来管理不同的工程&#xff0c;其中有一个是第一次打开软件的时候创建的。 新建一个工程 使用stm32cubeMX生成程序 生成之后直接打开&#xff0c;由于有一些.c.h文件是我们自己建立的&#xff0c;所以需要手动添加进工程…

Linux的开发工具gcc Makefile gdb的学习

一&#xff1a;gcc/g 1. 1 背景知识 1. 预处理&#xff08;进行宏替换) 预处理 ( 进行宏替换 ) 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。 预处理指令是以#号开头的代码行。 实例: gcc –E hello.c –o hello.i 选项“-E”,该选项的作用是让 gcc 在预处理结…

Unicode编码检查, 字符计算, Utf8与Utf16互转, GBK字符计算

CUnicodeUtils #pragma once #include <stdint.h> #include <string>class CUnicodeUtils { public:// // brief: 获取UTF16字符个数// param: pData 数据(UTF16编码, 大端字节序或小端字节序, 可包含BOM)// param: size 数据长度(字节)//…

MySQL日期类型选择建议

我们平时开发中不可避免的就是要存储时间&#xff0c;比如我们要记录操作表中这条记录的时间、记录转账的交易时间、记录出发时间、用户下单时间等等。你会发现时间这个东西与我们开发的联系还是非常紧密的&#xff0c;用的好与不好会给我们的业务甚至功能带来很大的影响。所以…

对话型AI:Auto Possess Player Auto Possess AI

Auto Possess Player “Auto Possess Player” 是一个常见于游戏开发&#xff0c;尤其是在 Unreal Engine 中的术语。它指的是一个功能或设置&#xff0c;使得一个特定的角色或对象在游戏开始时自动接管玩家的控制权。以下是一些关键点&#xff1a; 含义 自动控制&#xff…