条码扫描器

news2024/11/25 4:38:49

介绍

条码扫描器,又称为条码阅读器、条码扫描枪、条形码扫描器、条形码扫描枪及条形码阅读器。它是用于读取条码所包含信息的阅读设备,利用光学原理,把条形码的内容解码后通过数据线或者无线的方式传输到电脑或者别的设备。广泛应用于超市、物流快递、图书馆等扫描商品、单据的条码

插件安装命令

npm install @zxing/library

代码部分

<template>
    <div class="code-reader-content">
        <div class="page">
            <video ref="video" autoplay id="video" height="200"></video>
            <p v-if="videoInputDevicesArray.length === 0">{{ textContent }}</p>
        </div>
        <div class="scan-box">
            <div class="frame upper-left"></div>
            <div class="frame upper-right"></div>
            <div class="frame lower-right"></div>
            <div class="frame lower-left"></div>
            <div class="pointer-box">
                <div class="pointer"></div>
            </div>
            <div v-show="tipShow" class="tip">{{ tipMsg }}</div>
            <div class="btn-switch" @click="toggle"></div>
            <button @click="handleScanComplete" class="btn-wc">扫描完成</button>
        </div>
    </div>
</template>

功能部分

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { BrowserMultiFormatReader } from '@zxing/library';

import { useRouter } from 'vue-router'
const router = useRouter()
import { defineEmits } from 'vue';

const emits = defineEmits(['scan-complete']);

const handleScanComplete = (val1) => {
    console.log('扫描完成按钮被点击了');
    emits('scan-complete', true, val1);
};

const codeReader = ref(null);
const tipMsg = ref('正在尝试识别....');
const tipShow = ref(true);
const textContent = ref(undefined);
const videoInputDevicesArray = ref([]);
const deviceId = ref('');
const isEswitch = ref(false);
let timer = null;

// 开启扫描
const openScan = async () => {
    codeReader.value = await new BrowserMultiFormatReader();
    codeReader.value
        .getVideoInputDevices()
        .then(async (videoInputDevices) => {
            tipShow.value = true;
            tipMsg.value = '正在尝试识别....';
            videoInputDevicesArray.value = videoInputDevices;
            if (videoInputDevicesArray.value.length > 1) {
                deviceId.value = videoInputDevicesArray.value[1].deviceId;
            } else {
                deviceId.value = videoInputDevicesArray.value[0].deviceId;
            }

            decodeFromInputVideoFunc();
            console.log('codeReader', codeReader.value);
            console.log('----------------');
            console.log('deviceId', deviceId.value);
            console.log('-------------------');
            console.log('videoInputDevicesArray', videoInputDevicesArray.value);
        })
        .catch(() => {
            tipShow.value = false;
        });
};

// 解码部分
const decodeFromInputVideoFunc = () => {
    if (videoInputDevicesArray.value.length === 0) {
        textContent.value = '初始化摄像头失败';
        document.getElementById('video').style.display = 'none';
        return;
    }

    codeReader.value.reset();
    codeReader.value.decodeFromInputVideoDeviceContinuously(
        deviceId.value,
        'video',
        (result) => {
            tipMsg.value = '正在扫描';
            if (result) {
                tipMsg.value = '扫描成功!';
                setTimeout(() => {
                    tipMsg.value = '解析完成';
                    handleScanComplete(result.text)
                }, 1000); // 延迟1秒钟
                console.log('扫描成功123', result);
                console.log('result123', result.text);
                // tipShow.value = false;
                // window && window.getResultEvent(result);
                // window?.parent?.Gikam?.toast('扫码成功');
                // codeReader.value.reset();
                // codeReader.value.stopContinuousDecode();
                // cid.value = result.text

                // // 发送POST请求给服务器
                // fetch('http://localhost:2303/mtg/parse-product', {
                //     method: 'POST',
                //     headers: {
                //         'Content-Type': 'application/json'
                //     },
                //     body: JSON.stringify({ barcode: result.text })
                // })
                // .then(response => response.json())
                // .then(data => {
                //     // 从服务器获取到产品信息
                //     console.log('产品信息:', data);
                //     // 进行其他操作...
                // })
                // .catch(error => {
                //     console.error('请求出错:', error);
                // });

                // router.push('/scanbook')
            }
        }
    );
};

const cutover = () => {
    if (
        videoInputDevicesArray.value &&
        videoInputDevicesArray.value.length > 1
    ) {
        if (deviceId.value === videoInputDevicesArray.value[0].deviceId) {
            deviceId.value = videoInputDevicesArray.value[1].deviceId;
        } else {
            deviceId.value = videoInputDevicesArray.value[0].deviceId;
        }
    }
    codeReader.value.stopStreams();
};

// 切换摄像头
const toggle = async () => {
    codeReader.value.stopStreams();
    timer = setTimeout(() => {
        timer = null;
    }, 2000);
    if (timer) {
        await codeReader.value.tryPlayVideo('video');
        cutover();
        decodeFromInputVideoFunc();
    }
};

onMounted(() => {
    openScan();
});

onBeforeUnmount(() => {
    codeReader.value.stopContinuousDecode();
    codeReader.value.reset();
});
</script>

样式部分

<style lang="less" scoped>
.code-reader-content {
    .page {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 100%;
        height: 200px;

        #video {
            // height: 100%;
            width: 100%;
            object-fit: fill;
        }
    }

    .scan-box {
        position: absolute;
        left: 50%;
        top: 58%;
        transform: translate(-50%, -90%);
        height: 20%;
        width: 80%;

        .frame {
            position: absolute;
            width: 15px;
            height: 15px;
            border: 3px solid transparent;
        }

        .upper-left {
            top: 0;
            left: 0;
            border-left-color: rgba(66, 133, 244, 1);
            border-top-color: rgba(66, 133, 244, 1);
        }

        .upper-right {
            top: 0;
            right: 0;
            border-right-color: rgba(66, 133, 244, 1);
            border-top-color: rgba(66, 133, 244, 1);
        }

        .lower-right {
            bottom: 0;
            right: 0;
            border-bottom-color: rgba(66, 133, 244, 1);
            border-right-color: rgba(66, 133, 244, 1);
        }

        .lower-left {
            bottom: 0;
            left: 0;
            border-left-color: rgba(66, 133, 244, 1);
            border-bottom-color: rgba(66, 133, 244, 1);
        }

        .pointer-box {
            position: absolute;
            top: 0;
            left: 0;
            width: 98%;
            height: 100%;
            overflow: hidden;

            .pointer {
                height: 3px;
                background-image: linear-gradient(to right,
                        transparent 0%,
                        rgba(66, 133, 244, 1) 50%,
                        transparent 100%);
                transform: translateY(-3px);
                animation: move 2s linear infinite;
            }

            @keyframes move {
                0% {
                    transform: translateY(-3px);
                }

                100% {
                    transform: translateY(calc(20vh - 3px));
                }
            }
        }

        .tip {
            position: absolute;
            left: 50%;
            top: 122%;
            transform: translate(-50%, 0);
            white-space: nowrap;
            color: rgb(176, 209, 28);
            font-size: 16px;
        }

        .btn-switch {
            position: absolute;
            left: 50%;
            top: 140%;
            width: 20px;
            height: 20px;
            transform: translate(-50%, 0);
            background-color: red;
        }

        .btn-wc {
            position: absolute;
            left: 50%;
            top: 160%;
            transform: translate(-50%, 0);
        }
    }
}
</style>

效果图预览

扫描中...                    扫描完

 

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

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

相关文章

2024年腾讯云4核8G12M轻量应用服务器测评,2月更新

4核8G服务器支持多少人同时在线访问&#xff1f;阿腾云的4核8G服务器可以支持20个访客同时访问&#xff0c;关于4核8G服务器承载量并发数qps计算测评&#xff0c;云服务器上运行程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&…

搜维尔科技:分析OptiTrack光学动作捕捉应用领域!

虚拟制作 当今虚拟制作阶段低延迟、超精确摄像机跟踪的事实上的标准。 用于运动科学的 OptiTrack OptiTrack 系统提供世界领先的测量精度和简单易用的工作流程&#xff0c;为研究人员和生物力学师的研究提供理想的 3D 跟踪数据。对所有主要数字测力台、EMG 和模拟设备的本机即…

Kernelized Correlation Filters KCF算法原理详解(阅读笔记)(待补充)

KCF 目录 KCF预备知识1. 岭回归2. 循环移位和循环矩阵3. 傅里叶对角化4. 方向梯度直方图&#xff08;HOG&#xff09; 正文1. 线性回归1.1. 岭回归1.2. 基于循环矩阵获取正负样本1.3. 基于傅里叶对角化的求解 2. 使用非线性回归对模型进行训练2.1. 应用kernel-trick的非线性模型…

机构如何搭建一个在线课程教学平台?

随着数字化教育的兴起&#xff0c;越来越多的教育机构开始考虑建立自己的在线课程教学平台。这一趋势不仅顺应了时代的发展&#xff0c;而且为教育行业带来了诸多便利和优势。构建一个在线教学平台可以帮助机构拓宽服务范围、提升教学质量、增强学生体验&#xff0c;并且能够有…

【机器学习】数据清洗——基于Pandas库的方法删除重复点

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

《Solidity 简易速速上手小册》第6章:优化 Gas 消耗和性能(2024 最新版)

文章目录 6.1 理解 Gas 和交易成本6.1.1 基础知识解析更深入的理解优化的关键点 6.1.2 重点案例&#xff1a;优化合约以降低 Gas 成本案例 Demo&#xff1a;创建一个经济高效的财务管理合约案例代码FinancialManagementContract.sol 测试和验证拓展功能 6.1.3 拓展案例 1&#…

【plt.pie绘制饼图】:从入门到精通,只需一篇文章!【Matplotlib可视化】

【&#x1f4ca;plt.pie绘制饼图】&#xff1a;从入门到精通&#xff0c;只需一篇文章&#xff01;【Matplotlib可视化】&#xff01; 利用Matplotlib进行数据可视化示例 &#x1f335;文章目录&#x1f335; &#x1f3a8; 一、饼图初探&#xff1a;基本概念与用途&#x1f4a…

软件测试系列:移动端安卓APP测试必备之ADB命令 (二)

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

AD24-Objects元素、特殊复制粘贴、多根走线、自动布线、泪滴

一、Objects元素的隐藏与显示 1、Altium Transparent 2D与Altium Standard 2D的区别 1) Altium Transparent 2D 2) Altium Standard 2D 二、特殊复制粘贴 1、如何把元件带位号、带网络从当前PCB调用到另外的PCB中 三、多根走线与多根走线设置 四、Active Route 的自动布线辅助…

RSA加密,解密,加签及验签

目录 1.说明 2.加密和加签的区别 3.后端加密&#xff0c;解密&#xff0c;加签及验签示例 4.前端加密&#xff0c;解密&#xff0c;加签及验签示例 5.前端加密&#xff0c;后端解密&#xff0c;前端加签&#xff0c;后端验签 6.注意事项 1.说明 RSA算法是一种非对称加密…

压缩感知——革新数据采集的科学魔法

引言&#xff1a; 在数字时代&#xff0c;数据以及数据的收集和处理无处不在。压缩感知(Compressed Sensing, CS)是一种新兴的数学框架&#xff0c;它挑战了我们传统上对数据采集和压缩的看法&#xff0c;给医学图像、天文观测、环境监测等领域带来了颠覆性的影响。但到底什么…

白话微机:5.解释串行接口以及一些考研面试问题

一. 前言&#xff08;回顾世界观&#xff09; 很久很久以前&#xff0c;有这样一个世界&#xff0c;这个世界有着现实世界一样的元素&#xff1a;那里的人又有一个别的名字叫做“数据”&#xff0c;人有0有1&#xff1b;人们也有住房&#xff0c;这些住房在这个世界叫做“存储器…

Apache DolphinScheduler中ZooKeeperCDH不兼容问题的解决方案

背景 看到Apache DolphinScheduler社区群有很多用户反馈和讨论这块问题&#xff0c;针对不兼容的问题&#xff0c;不仅需要自己重新编译各一个新包&#xff0c;而且因为默认是使用zk-3.8的配置&#xff0c;所以会出现不兼容问题。使用zk-3.4配置即可适配3.4.x 解决办法&#…

ffmpeg for android编译全过程与遇到的问题

编译前准备 编译环境&#xff1a;Ubuntu16&#xff0c;可自行下载VMWare最新版并百度永久许可证或在服务器上安装Ubuntu ffmpeg源码&#xff1a;ffmpeg4.2.2 NDK下载&#xff1a;Android NDK r21e 有条件的最好还是在Liunx平台下编译吧&#xff0c;Windows平台下编译坑更多…

使用openeuler 22.03替代CentOS 7.9,建立虚拟机详细步骤

进入浏览器搜索网址下载openeuler 22.03镜像文件 https://mirrors.huaweicloud.com/openeuler/openEuler-22.03-LTS-SP3/ISO/x86_64/openEuler-22.03-LTS-SP3-x86_64-dvd.iso 打开VMware Workstation新建一个虚拟机&#xff1a; 自定义虚拟机位置 加入下载好的openeuler镜像文件…

算法刷题:最大连续1的个数

最大连续1的个数 .题目链接题目详情题目解析算法原理滑动窗口定义指针和其他变量进窗口判断出窗口结束更新结果 我的答案 . 题目链接 最大连续1的个数 题目详情 题目解析 将题目转化为求一个最长的字串,字串中0的个数不能大于k个 算法原理 滑动窗口 这道题采用滑动窗口的…

33、IO/标准IO对图片操作练习及文件IO相关练习20240219

一、使用fread和fwrite完成两个图片文件的拷贝&#xff08;标准IO&#xff09;。 代码&#xff1a; #include<myhead.h>int main(int argc, const char *argv[]) {FILE *srcfpNULL;FILE *destfpNULL;if((srcfpfopen("./hongfeng.bmp","r"))NULL ||…

Discuz! X收藏列表页调用封面图片详细教程

Discuz! X默认收藏列表不显示封面图&#xff0c;我们接到客户需求要开发封面图功能在帖子列表&#xff0c;这是我们整理好的详细教程&#xff0c;下载即可查看 修改后&#xff0c;显示封面的收藏列表截图&#xff1a; 详细开发教程下载地址&#xff1a;Discuz! X收藏列表页调用…

把Llama2封装为API服务并做一个互动网页

最近按照官方例子&#xff0c;把Llama2跑起来了测试通了&#xff0c;但是想封装成api服务&#xff0c;耗费了一些些力气 参考&#xff1a;https://github.com/facebookresearch/llama/pull/147/files 1. 准备的前提如下 按照官方如下命令&#xff0c;可以运行成功 torchrun -…

【EI会议征稿通知】第五届信息科学与并行、分布式处理国际学术会议(ISPDS 2024)

第五届信息科学与并行、分布式处理国际学术会议&#xff08;ISPDS 2024&#xff09; 2024 5th International Conference on Information Science, Parallel and Distributed Systems 第五届信息科学与并行、分布式处理国际学术会议&#xff08;ISPDS 2024&#xff09;定于20…