Android 二维码相关(三)

Android 二维码相关(三)

本篇文章主要讲下二维码扫描相关.

1: 权限相关

由于文中需要使用Camera以及surfaceview,所以我们需要提前申请相机权限:

<uses-permission android:name="android.permission.CAMERA" />

2: 添加SurfaceView预览

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".ScanActivity"><SurfaceViewandroid:layout_width="match_parent"android:layout_height="match_parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"android:id="@+id/surface"/>
</androidx.constraintlayout.widget.ConstraintLayout>

3: 初始化相机

通过SurfaceView我们获取SurfaceHolder:

surfaceView = findViewById(R.id.surface);
SurfaceHolder holder = surfaceView.getHolder();
holder.addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(SurfaceHolder holder) {}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {}
});
  1. surfaceCreated中我们初始化相机配置
  2. surfaceDestroyed 中我们重置参数
3.1 startCamera()
private void startCamera() {Camera open = Camera.open();Camera.Parameters parameters = open.getParameters();parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);open.setParameters(parameters);open.setDisplayOrientation(90);open.setPreviewCallback(new Camera.PreviewCallback() {@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {}});try {open.setPreviewDisplay(surfaceView.getHolder());open.startPreview();} catch (IOException e) {e.printStackTrace();}
}
3.2 stopCamera()
private void stopCamera() {if (open != null) {open.stopPreview();open.setPreviewCallback(null);open.release();open = null;}
}
3.3 Camera.PreviewCallback

具体的解析方法,以及数据来源根据Camera.PreviewCallback 的回调来实现:

  1. 获取数据的宽高

    Camera.Size previewSize = camera.getParameters().getPreviewSize();
    int width = previewSize.width;
    int height = previewSize.height;
    
  2. 将预览数据转换为二进制位图

     PlanarYUVLuminanceSource planarYUVLuminanceSource = new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(planarYUVLuminanceSource));
    
  3. 设置解码参数

    EnumMap<DecodeHintType, Object> decodeHintTypeObjectEnumMap = new EnumMap<>(DecodeHintType.class);
    Collection<BarcodeFormat> list = new ArrayList<>();
    list.addAll(EnumSet.of(BarcodeFormat.QR_CODE));
    decodeHintTypeObjectEnumMap.put(DecodeHintType.POSSIBLE_FORMATS, list);
    
  4. 解码

    创建MultiFormatReader对象,用于解码.并通过setHints方法设置解码格式

    MultiFormatReader multiFormatReader = new MultiFormatReader();
    multiFormatReader.setHints(decodeHintTypeObjectEnumMap);
    try {Result decode = multiFormatReader.decode(binaryBitmap);String text = decode.getText();Log.i("xxxxx", "onPreviewFrame: " + text);
    } catch (Throwable e) {Log.e("xxxxx", "onPreviewFrame: ", e);
    }
    

注: onPreviewFrame是Android相机预览帧回调函数,它会在每一帧预览数据可用时被调用.

完整的代码如下:


public class ScanActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback {private SurfaceView surfaceView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_scan);surfaceView = findViewById(R.id.surface);SurfaceHolder holder = surfaceView.getHolder();holder.addCallback(this);}Camera open;private void startCamera() {Camera open = Camera.open();Camera.Parameters parameters = open.getParameters();parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);open.setParameters(parameters);open.setDisplayOrientation(90);open.setPreviewCallback(this);try {open.setPreviewDisplay(surfaceView.getHolder());open.startPreview();} catch (IOException e) {e.printStackTrace();}}private void stopCamera() {if (open != null) {open.stopPreview();open.setPreviewCallback(null);open.release();open = null;}}@Overridepublic void surfaceCreated(SurfaceHolder holder) {startCamera();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {stopCamera();}@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {if (camera == null || camera.getParameters() == null) return;Camera.Size previewSize = camera.getParameters().getPreviewSize();int width = previewSize.width;int height = previewSize.height;//预览数据转二进制位图PlanarYUVLuminanceSource planarYUVLuminanceSource = new PlanarYUVLuminanceSource(data, width, height, 0, 0, width, height, false);BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(planarYUVLuminanceSource));// 设置解码参数EnumMap<DecodeHintType, Object> decodeHintTypeObjectEnumMap = new EnumMap<>(DecodeHintType.class);Collection<BarcodeFormat> list = new ArrayList<>();list.addAll(EnumSet.of(BarcodeFormat.QR_CODE));decodeHintTypeObjectEnumMap.put(DecodeHintType.POSSIBLE_FORMATS, list);MultiFormatReader multiFormatReader = new MultiFormatReader();multiFormatReader.setHints(decodeHintTypeObjectEnumMap);try {Result decode = multiFormatReader.decode(binaryBitmap);String text = decode.getText();Log.i("xxxxx", "onPreviewFrame: " + text);} catch (Throwable e) {Log.e("xxxxx", "onPreviewFrame: ", e);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/782055.shtml

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

相关文章

【DETR系列目标检测算法代码精讲】01 DETR算法01 DETR算法框架和网络结构介绍

为什么要有DETR 总所周知&#xff0c;传统的目标检测算法非常依赖于anchor和nms等手工设计操作&#xff0c;非常费时费力&#xff0c;自然而然的就产生了取消这些操作的想法。但是我们首先需要思考的是&#xff0c;为什么我们需要anchor和nms&#xff1f; 因为我们是没有指定…

Altium Designer许可需求分析

在电子设计的世界中&#xff0c;Altium Designer已成为设计师们的得力助手。然而&#xff0c;如何进行有效的许可需求分析&#xff0c;以确保软件的高效使用和企业的可持续发展&#xff1f;本文将带您了解如何进行Altium Designer的许可需求分析&#xff0c;让您在设计的道路上…

安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 从0开始 工具操作解析【三】

同类博文; 安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析 安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析【二】-CSDN博客 回顾以往 在以前的博文简单介绍了这款工具的rom制作全程。今天针对这款工具的…

【Java多线程】8——CompletableFuture

8 CompletableFuture ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个s…

【UI框架】——保姆式使用教程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

win11 环境配置 之 Jmeter(JDK17版本)

一、安装 JDK 1. 安装 jdk 截至当前最新时间&#xff1a; 2024.3.27 jdk最新的版本 是 官网下载地址&#xff1a; https://www.oracle.com/java/technologies/downloads/ 建议下载 jdk17 另存为到该电脑的 D 盘下&#xff0c;新建jdk文件夹 开始安装到 jdk 文件夹下 2. 配…

Java23种常见设计模式汇总

七大原则网站地址&#xff1a;设计模式7大原则&#xff0b;类图关系-CSDN博客 创建型设计模式&#xff1a;创建型设计模式合集-CSDN博客 七大结构型设计模式&#xff1a;7大结构型设计模式-CSDN博客 11种行为型设计模式&#xff1a; 11种行为型模式&#xff08;上&#xff0…

Oracle 19c 高可用部署实战系列之Data Guard理论与实战

课程介绍 Oracle Data Guard确保企业数据的高可用性、数据保护和灾难恢复。 Oracle Data Guard提供了一组全面的服务&#xff0c;用于创建、维护、管理和监视一个或多个备用数据库&#xff0c;使生产Oracle数据库能够在灾难和数据损坏中幸存下来。Oracle Data Guard将这些备用…

我于窗中窥月光,恰如仰头见“链表”(Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

Python计算物理粒子及拉格朗日和哈密顿动力学

&#x1f3af;要点 运动和计算&#xff0c;牛顿运动定律&#xff0c;&#x1f3af;Python符号计算粒子速度随时间变化的微分方程&#xff0c;并绘制运动趋势图。单粒子一维物理运动&#xff0c;数学方程表示和计算&#xff1a;&#x1f3af;在重力作用下和空气阻力为线性&…

java项目通用Dockerfile

创建Dockerfile文件&#xff0c;放到项目根目录下和pom.xml同级别 仅需修改为自己项目端口号即可&#xff0c;其他的无需改动 FROM openjdk:11.0.11-jre-slimCOPY target/*.jar .EXPOSE 8080ENTRYPOINT java -jar *.jar构建语句(注意末尾的点 . ) docker build -t container…

代码随想录算法训练营第38天 | 509.斐波那契数, 70。爬楼梯, 746.使用最小花费爬楼梯

Leetcode - 509&#xff1a;斐波那契数 题目&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(…

协程的好处

轻量级&#xff1a;协程是比线程更轻量级的任务单元&#xff0c;它们在应用程序中的创建和销毁的开销较低。相比于线程&#xff0c;可以创建大量的协程而不会造成显著的资源消耗。 协作式调度&#xff1a;协程采用协作式调度方式&#xff0c;即协程主动让出执行权给其他协程&am…

实现公网数据传输给内网(使用frp)

如果你想在内网设备2上运行 FRP 服务器端&#xff08;frps&#xff09;&#xff0c;在内网设备3上运行 FRP 客户端&#xff08;frpc&#xff09;&#xff0c;并使用公网设备1来完成数据传输&#xff0c;你需要通过公网设备1来访问设备2&#xff0c;然后设备2再转发请求到设备3。…

Android Studio Iguana | 2023.2.1 补丁 1

Android Studio Iguana | 2023.2.1 Canary 3 已修复的问题Android Gradle 插件 问题 295205663 将 AGP 从 8.0.2 更新到 8.1.0 后&#xff0c;任务“:app:mergeReleaseClasses”执行失败 问题 298008231 [Gradle 8.4][升级] 由于使用 kotlin gradle 插件中已废弃的功能&#…

C语言例1-3:设 int a; ,语句 for(a=0;a==0;a++); 和语句 for(a=0;a=0;a++); 执行的循环次数分别是

答案&#xff1a;1,0 代码如下&#xff1a; #include<stdio.h> int main(void) {int a;for(a0;a0;a){printf("1\n");} return 0; } 结果如下&#xff1a; 代码如下&#xff1a; #include<stdio.h> int main(void) {int a;for(a0;a0;a){printf("…

手写三维点云配准的迭代最近点(ICP)算法

在本篇博客中,主要深入研究迭代最近点(ICP)算法,特别是针对三维点云配准的实现。分析一个C++代码片段并解释其关键组成部分。(主要参考高博的ICP算法) 简介 ICP是计算机视觉和机器人领域广泛使用的技术,用于将两组三维点进行配准。其主要应用是将一组观测点与参考模型进…

深度剖析Redis持久化机制:RDB与AOF的双轮驱动与混合策略

引言&#xff1a; 在现代分布式系统中&#xff0c;Redis凭借其出色的性能与丰富的数据结构&#xff0c;已成为缓存、队列、会话存储等场景的首选解决方案。然而&#xff0c;作为内存数据库&#xff0c;Redis如何在断电、重启等意外情况中确保数据的持久性呢&#xff1f;答案就…

京东云8核16G服务器配置租用优惠价格1198元1年、4688元三年

京东云轻量云主机8核16G服务器租用优惠价格1198元1年、4688元三年&#xff0c;配置为8C16G-270G SSD系统盘-5M带宽-500G月流量&#xff0c;华北-北京地域。京东云8核16G服务器活动页面 yunfuwuqiba.com/go/jd 活动链接打开如下图&#xff1a; 京东云8核16G服务器优惠价格 京东云…

杰理芯片AC79——物联网远程点亮/关闭LED灯

杰理芯片的封装简直太香了&#xff08;比STM32香多了&#xff09;&#xff0c;SDK也封装得很好&#xff0c;对于我这种手残党简直不要太友好。赶紧学起来&#xff0c;快速实现你想要的功能吧&#xff01; 芯片选型 杰理AC79 资料文档 环境搭建以及点亮第一盏灯请访问&#x…