当前位置: 首页 > news >正文

09篇--图片的水印添加(掩膜的运用)

如何添加水印?

添加水印其实可以理解为将一张图片中的某个物体或者图案提取出来,然后叠加到另一张图片上。具体的操作思想是通过将原始图片转换成灰度图,并进行二值化处理,去除背景部分,得到一个类似掩膜的图像。然后将这个二值化图像与另一张图片中要添加水印的区域进行“与”运算,使得目标物体的形状出现在要添加水印的区域。最后,将得到的目标物体图像与要添加水印的区域进行相加,就完成了添加水印的操作。这样可以实现将一个图像中的某个物体或图案叠加到另一个图像上,从而实现添加水印的效果。

何为掩膜?

掩膜(Mask)是一种在图像处理中常见的操作,它用于选择性地遮挡图像的某些部分,以实现特定任务的目标。掩膜通常是一个二值化图像,并且与原图像的大小相同,其中目标区域被设置为1(或白色),而其他区域被设置为0(或黑色),并且目标区域可以根据HSV的颜色范围进行修改

没听懂没关系,下面开始详细介绍

示例演示

将准备好的logo图作为水印模板,本篇以下图作为水印模板与目标模板

注: 本示例以白底的水印模板演示,所以我们需要准备一张黑底的掩膜(目标区域位为白色) 

        黑底的水印模板则不需要多准备一张黑底的掩膜,直接从下面第二步开始即可

如果你是在分不清要准备什么底的掩膜,那就都准备吧,两个掩膜都试一试

第一步

首先我们需要先将颜色空间转换成HSV,再制造一个掩膜(目标区域为黑色,后面要进行与运算)用来确定logo的范围。

方法一:水印模板上出现了两种颜色,所以要制作两个掩膜,再将两个掩膜合为一个掩膜(或运算),这样就可以筛选水印模板中的所有logo信息,掩膜如下:
 

但直接调用接口制作的掩膜(如上图)中,目标区域是白色的,如果你需要的是目标区域为黑色的掩膜,建议用下面的第二种方法,直接得到目标区域为黑色的掩膜

方法二:掩膜本身也就是一个二值化的二维数组,我们也可以对原图灰度化后在进行二值化,得到的结果如下,二值化后的图(右侧)也可以用做掩膜使用。

 第二步

在目标模板上利用ROI切割出自己想要的区域(你想将水印添加的区域),ROI切割可以参照我之前的文章              

 06篇--图片目标区域的 ROI切割-CSDN博客

第三步

掩膜目标模板进行与运算,之后:

  • 掩膜(白色部分)会目标模板(相应的部分)替代
  • 掩膜(黑色部分)会目标模板(相应的部分)替代

得到的结果与切割部分进行对比:

将切割出来的部分img_roi掩膜进行与运算,之后:

  • 掩膜(白色部分)会目标模板(相应的部分)替代
  • 掩膜(黑色部分)会目标模板(相应的部分)替代

得到的结果与切割部分进行对比:

第四步

就是将图像对应的数组中的对应元素进行相加(一定要注意这里的两个数组是规格相同的,也就是说要么都是灰度图,要么都是彩图),其过程如下图所示

cv2.add()函数,用于执行上面的过程,可得到如下结果

第五步

将已经融合好的部分替换掉目标模板中的相应部分(被切割的那一部分),利用切片进行。

  

 如果还是对上述步骤有疑问,欢迎在评论区提问。

 代码演示

import cv2
import numpy as np#读取图像
logo = cv2.imread('image/logo_1.png')
img = cv2.imread('image/logo_demo.png')#第一种方法获取掩膜
#先转换颜色空间
logo_hsv = cv2.cvtColor(logo,cv2.COLOR_BGR2HSV)#制作红色掩膜
red_min= np.array([0,43,46])
red_max = np.array([10,255,255])
logo_mask_1_1 = cv2.inRange(logo_hsv,red_min,red_max)#制作黑色掩膜
black_min = np.array([0,0,0])
black_max = np.array([180,255,220])
logo_mask_1_2 = cv2.inRange(logo_hsv,black_min,black_max)#将两个掩膜合并
logo_mask_1 = cv2.bitwise_or(logo_mask_1_1,logo_mask_1_2)#第二种方法获取掩膜
#灰度化
logo_gray = cv2.cvtColor(logo,cv2.COLOR_BGR2GRAY)
#二值化结果充当掩膜
_,logo_mask_2 = cv2.threshold(logo_gray,127,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
#获取掩膜大小
rows,cols = logo.shape[:2]#ROI切割
#要切割的矩形的top_left的坐标点
x1,y1 = 750,425
def ImgRoi(img,x1,y1):# 提取该图片的宽高h,w = img.shape[0], img.shape[1]#获取掩膜坐标,x2,y2x2 = x1 + colsy2 = y1 + rowsif x1<0 or x2>w or y1<0 or y2>h:print("要切割的区域是不合适的")else:# 给要切割的内容画个框# cv2.rectangle(img, (x1-2, y1-2), (x2+2, y2+2), (0, 0, 255), 2)# 保存要切割的内容img_roi = img[y1:y2, x1:x2]return img_roiimg_roi = ImgRoi(img,x1,y1)# 进行与运算
logo_mask = cv2.bitwise_and(logo,logo,mask=logo_mask_1)
img_roi_mask = cv2.bitwise_and(img_roi,img_roi,mask=logo_mask_2)#进行相加,得到融合的图像img_roi_mask,并合并到img中
img_roi_logo = cv2.add(img_roi_mask,logo_mask)
img[y1:(y1+rows), x1:(x1+cols)] = img_roi_logocv2.imshow('logo_mask',img)cv2.waitKey(0)

相关文章:

09篇--图片的水印添加(掩膜的运用)

如何添加水印&#xff1f; 添加水印其实可以理解为将一张图片中的某个物体或者图案提取出来&#xff0c;然后叠加到另一张图片上。具体的操作思想是通过将原始图片转换成灰度图&#xff0c;并进行二值化处理&#xff0c;去除背景部分&#xff0c;得到一个类似掩膜的图像。然后…...

Qt 使用modbus协议

Qt 框架下 使用modbus协议 一&#xff0c;使用Qt原生的 QModbusClient &#xff0c;比如QModbusTcpClient 1&#xff0c;因为modbus的读写 需要在同一个线程中&#xff0c;所以需要在主线程中利用moveToThread的方式&#xff0c;将业务逻辑封装到 子线程中。 2&#xff0c;m…...

pip离线安装一个github仓库

要使用pip安装一个本地Git仓库&#xff0c;你可以按照以下步骤操作&#xff1a; 确保你已经克隆了Git仓库到本地。 进入仓库所在的目录。 使用pip安装。 以下是具体的命令&#xff1a; 克隆Git仓库到本地&#xff08;替换下面的URL为你的仓库URL&#xff09; git clone https…...

【ETCD】【源码阅读】深入分析 storeTxnWrite.Put方法源码

该方法是 storeTxnWrite 类型中的核心方法&#xff0c;负责将键值对存储到数据库&#xff0c;同时处理键的元数据&#xff08;如版本、修订号、租约&#xff09;并管理租约关联。 目录 一、完整代码二、方法详解方法签名1. 计算修订号并初始化变量2. 检查键是否已存在3. 生成索…...

桥接模式的理解和实践

桥接模式&#xff08;Bridge Pattern&#xff09;&#xff0c;又称桥梁模式&#xff0c;是一种结构型设计模式。它的核心思想是将抽象部分与实现部分分离&#xff0c;使它们可以独立地进行变化&#xff0c;从而提高系统的灵活性和可扩展性。本文将详细介绍桥接模式的概念、原理…...

【Rust自学】3.2. 数据类型:标量类型

3.2.0. 写在正文之前 欢迎来到Rust自学的第三章&#xff0c;一共有6个小节&#xff0c;分别是: 变量与可变性数据类型&#xff1a;标量类型&#xff08;本文&#xff09;数据类型&#xff1a;复合类型函数和注释控制流&#xff1a;if else控制流&#xff1a;循环 通过第二章…...

【Leetcode Top 100】199. 二叉树的右视图

问题背景 给定一个二叉树的 根节点 r o o t root root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 数据约束 二叉树的节点个数的范围是 [ 0 , 100 ] [0,100] [0,100] − 100 ≤ N o d e . v a l ≤ 100…...

Java并发编程框架之其他并发工具

选错了就选错了&#xff0c;不要一遍一遍的后悔&#xff0c;总是一遍遍的想&#xff0c;当时怎么样就好了&#xff0c;不要欺负当时的自己&#xff0c;当时你一个人站在迷雾中&#xff0c;也很迷茫&#xff0c;就算重新来一遍&#xff0c;以你当时的阅历和心智&#xff0c;还是…...

MinerU:PDF文档提取工具

目录 docker一键启动本地配置下载模型权重文件demo.py使用命令行启动GPU使用情况 wget https://github.com/opendatalab/MinerU/raw/master/Dockerfile docker build -t mineru:latest .docker一键启动 有点问题&#xff0c;晚点更新 本地配置 就是在Python环境中配置依赖和…...

Unity性能优化---使用SpriteAtlas创建图集进行批次优化

在日常游戏开发中&#xff0c;UI是不可缺少的模块&#xff0c;而在UI中又使用着大量的图片&#xff0c;特别是2D游戏还有很多精灵图片存在&#xff0c;如果不加以处理&#xff0c;会导致很高的Batches&#xff0c;影响性能。 比如如下的例子&#xff1a; Batches是9&#xff0…...

wazuh-modules-sca-scan

sca模块主函数wm_sca_main -> wm_sca_start 检查policy文件中的每一个项目wm_sca_check_policy static int wm_sca_check_policy(const cJSON * const policy, const cJSON * const checks, OSHash *global_check_list) {if(!policy) {return 1;}const cJSON * const id c…...

力扣-图论-15【算法学习day.65】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…...

JS萤石云录像回放拖动进度条无法正常播放

问题描述&#xff1a; 本项目版本&#xff1a;vue2.6.12&#xff0c;webpack3.6.0&#xff0c;ezuikit-js0.7.2 在使用萤石云的JavaScript SDK做监控的直播、录像回放时&#xff0c;遇到部分设备的录像回放&#xff0c;无法根据控制面板的拖动进度条查看某时间段的录像。 官方…...

Spring Boot 启动时间优化全攻略

引言 随着 Spring Boot 的广泛应用&#xff0c;开发者享受到了快速开发和自动化配置的便利。然而&#xff0c;随着项目复杂度的增加&#xff0c;Spring Boot 项目启动时间也变得越来越长&#xff0c;这在开发、调试和部署阶段可能会成为效率瓶颈。如何优化 Spring Boot 的启动…...

ubuntu服务器木马类挖矿程序排查、及安全管理总结

版本 24.04 由于GPU多卡服务器多人使用&#xff0c;需要链接隧道ssh等&#xff0c;容易中招挖矿脚本。 总的思路是&#xff0c;顺着进程的PID回溯最终的程序运行起点&#xff0c;这里可以先看一下日志&#xff1a; journalctl -u PID 通过 PID 精确定位进程的信息&#xff0c…...

redis 使用Lettuce 当redis挂掉重启之后 网络是怎么重新连接

Lettuce是一个高性能的Java Redis客户端&#xff0c;支持同步、异步和反应式编程模式 Lettuce的核心功能包括&#xff1a; ‌高性能‌&#xff1a;通过使用Netty作为底层网络通信框架&#xff0c;实现了非阻塞IO&#xff0c;提高了性能。‌丰富的API‌&#xff1a;提供了丰富…...

【PyTorch】实现在训练过程中自定义动态调整学习率

问题描述&#xff1a; 在使用 PyTorch 训练自定义神经网络时&#xff0c;我们希望能够动态地调整学习率&#xff0c;以便在训练过程中逐渐优化模型&#xff0c;避免过拟合并加速收敛。那么&#xff0c;如何在 PyTorch 中实现这一功能呢&#xff1f; 解决方案&#xff1a; 在训…...

【Flink-scala】DataStream编程模型总结

系列文章目录 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器 4.【Flink-scala】DataStream编程模型之水位线 5.【…...

语音芯片赋能可穿戴设备:开启个性化音频新体验

在科技日新月异的今天&#xff0c;语音芯片与可穿戴设备的携手合作&#xff0c;正引领我们步入一个前所未有的个性化音频时代。这一创新融合&#xff0c;用户可以享受到更加个性化、沉浸式的音频体验。下面将详细介绍语音芯片与可穿戴设备合作的优点和具体应用。 1. 定制化音效…...

JavaFX使用jfoenix的UI控件

jfoenix还是一个不错的样式&#xff0c;推荐使用&#xff0c;而且也可以支持scene builder中的拖拖拽拽 需要注意的是过高的javafx版本可能会使得某些样式或控件无法使用 比如alert控件&#xff0c;亲测javaFX 19版本可以正常使用 1.在pom.xml中引入依赖 GitHub地址https://gi…...

SpringBoot集成ENC对配置文件进行加密

在线MD5生成工具 配置文件加密&#xff0c;集成ENC 引入POM依赖 <!-- ENC配置文件加密 --><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.2</ver…...

基于AI对话生成剧情AVG游戏

游戏开发这个领域&#xff0c;一直有较高的学习门槛。作为一个非专业的游戏爱好者&#xff0c;如果想要开发游戏&#xff0c;往往受制于游戏引擎的专业程度&#xff0c;难以完成复杂的游戏项目。 AI IDE的诞生&#xff0c;提供了另外的一种思路&#xff0c;即通过AI 生成项目及…...

MAVEN--Maven的生命周期,pom.xml详解,Maven的高级特性(模块化、聚合、依赖管理)

目录 &#xff08;一&#xff09;Maven的生命周期 1.Maven的三套生命周期 2.Maven常用命令 &#xff08;二&#xff09;pom.xml详解 &#xff08;三&#xff09;Maven的高级特性&#xff08;模块化、聚合、依赖管理&#xff09; 1.Maven的依赖范围 2.版本维护 3.依赖传…...

SpringBoot的事务钩子函数

如果需要在A方法执行完成之后做一个不影响主方法运行的动作B&#xff0c;我们需要判断这个A方法是否存在事务&#xff0c;并且使用异步执行动作B&#xff1b; import org.springframework.transaction.support.TransactionSynchronization; import org.springframework.transa…...

uniapp滚动消息列表

两个相同的循环列表&#xff0c;循环滚动 <view class"winners_list uni-flex uni-column" :animation"animationData"><view v-for"(item, index) in winnersList" :key"index" class"li uni-flex uni-column"&g…...

基于python对pdf文件进行加密等操作

利用python对pdf文件进行操作 读取pdf-源码 import PyPDF2 # 读取pdf格式的文件 reader PyPDF2.PdfFileReader(示例文件/aaa.pdf) print(reader)# 读取指定页面的文件 page reader.getPage(0) # 输出当前页面的文本数据 print(page.extractText())读取pdf-源码解析 这段代…...

Three.js材质纹理扩散过渡

Three.js材质纹理扩散过渡 import * as THREE from "three"; import { ThreeHelper } from "/src/ThreeHelper"; import { LoadGLTF, MethodBaseSceneSet } from "/src/ThreeHelper/decorators"; import { MainScreen } from "/src/compone…...

【Leetcode 每日一题 - 扩展】45. 跳跃游戏 II

问题背景 给定一个长度为 n n n 的 0 0 0 索引 整数数组 n u m s nums nums。初始位置为 n u m s [ 0 ] nums[0] nums[0]。 每个元素 n u m s [ i ] nums[i] nums[i] 表示从索引 i i i 向前跳转的最大长度。换句话说&#xff0c;如果你在 n u m s [ i ] nums[i] nums[i…...

被裁20240927 --- YOLO 算法

背景 在云端部署ViSP&#xff0c;ViSP实现视觉伺服、yolo实现视觉跟踪。 开源的2d视觉跟踪算法有哪些&#xff1f; 开源的2D视觉跟踪算法有很多呢&#xff0c;这里给你推荐一些比较知名和常用的吧。 ByteTrackV2&#xff1a;这是一个通用2D跟踪算法&#xff0c;提出了分层的…...

AI技术架构:从基础设施到应用

人工智能&#xff08;AI&#xff09;的发展&#xff0c;正以前所未有的速度重塑我们的世界。了解AI技术架构&#xff0c;不仅能帮助我们看懂 AI 的底层逻辑&#xff0c;还能掌握其对各行业变革的潜力与方向。 一、基础设施层&#xff1a;AI 技术的坚实地基 基础设施层是 AI 技…...

植物大战僵尸辅助【控制台版本】

前面介绍了使用CE和OD的简单使用&#xff1a;CE和OD介绍和使用CE查找阳光的教学&#xff1a;阳光基地址和偏移地址&#xff0c;下面先使用最简单的控制台程序来实现修改阳光的功能。 项目地址 1.分析程序 我们的控制台程序想要修改植物大战僵尸游戏内的数据&#xff0c;它们…...

css中样式前加 css样式前面加个圆点

创建CSS样式,样式名称的前面需要加什么 1、我们只知道符号代表的意思是at&#xff0c;其翻译是 在... 例如media就是 在媒介上。没人规定本身具有什么意义&#xff0c;或者说就算规定了我们也改变不了&#xff0c;只需要知道其规定属性的用法即可。 2、px;}然后根据你自己索要…...

算法刷题Day18: BM41 输出二叉树的右视图

题目链接 描述 思路&#xff1a; 递归构造二叉树在Day15有讲到。复习一下&#xff0c;就是使用递归构建左右子树。将中序和前序一分为二。 接下来是找出每一层的最右边的节点&#xff0c;可以利用队列层次遍历。 利用队列长度记录当前层有多少个节点&#xff0c;每次从队列里…...

如何实现规范化LabVIEW编程

规范编写LabVIEW程序的目的是提高代码的可读性、可维护性、可扩展性&#xff0c;并确保团队成员能够高效地理解和修改代码。以下是一些关键建议&#xff0c;帮助您编写更专业的LabVIEW代码&#xff0c;并确保它易于后续的升级和维护&#xff1a; ​ 1. 合理的项目结构 目录结构…...

TQ15EG开发板教程:使用SSH登录petalinux

本例程在上一章“创建运行petalinux2019.1”基础上进行&#xff0c;本例程将实现使用SSH登录petalinux。 将上一章生成的BOOT.BIN与imag.ub文件放入到SD卡中启动。给开发板插入电源与串口&#xff0c;注意串口插入后会识别出两个串口号&#xff0c;都需要打开&#xff0c;查看串…...

Springboot+vue实现大文件上传

背景&#xff1a;为了实现大文件上传的功能 1新建数据表sql file_chunk CREATE TABLE file_chunk (id bigint UNSIGNED NOT NULL AUTO_INCREMENT,file_name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci NULL DEFAULT NULL COMMENT 文件名,chunk_nu…...

Linux笔记

常用的基本命令 查询某个安装包有没有安装某个软件 使用的命令是rpm -qa |grep 软件名字 卸载软件 rpm -e --nodeps 软件名称 查看已经启动的服务 netstat -tunlp 一般我们在Linux系统中上传文件一般上传到 /usr/local/src的目录下 查看防火墙的命令 firewall-cmd --sta…...

相机(Camera)成像原理详解

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 成像流程 1、光学相机的定义 顾名思义&#xff0c;光学相机就是利用光学原理进行成像的相机&#xff0c;而且市面上的相机几乎都是光学相机&#xff0c;只不过随着时代的发展&#xff0c;胶卷式…...

计算机网络知识点全梳理(一.TCP/IP网络模型)

目录 TCP/IP网络模型概述 应用层 什么是应用层 应用层功能 应用层协议 传输层 什么是传输层 传输层功能 传输层协议 网络层 什么是网络层 网络层功能 网络层协议 数据链路层 什么是数据链路层 数据链路层功能 物理层 物理层的概念和功能 写在前面 本系列文…...

后端接受前端传递数组进行批量删除

问题描述&#xff1a;当我们需要做批量删除功能的时候&#xff0c;我们循环单次删除的接口也能进行批量删除&#xff0c;但要删除100条数据就要调用100次接口&#xff0c;或者执行100次sql&#xff0c;这样系统开销是比较大的&#xff0c;那么我们直接采用接收的数组格式数据sq…...

理解数据结构 hashtable的简易理解思路

结构图 为了方便演示&#xff0c;下图中分区算法为下标取模 private int hashFun(int id) {//使用 hash并取模return id % size;}Hashtable的结构如图所示&#xff1a;是一个数组&#xff08;元素为各个链表的表头&#xff09; 多个链表组成&#xff0c;也就是说 hashtable 结…...

大数据面试题--企业面试真题

大数据面试题--企业面试真题 PlanHub 点击访问获取&#xff1a; 大数据面试体系专栏_酷兜科技​www.kudoumh.top/hlwai/85.html 点击访问获取&#xff1a; 大数据面试体系专栏_酷兜科技​www.kudoumh.top/hlwai/85.html 大数据面试题汇总 HDFS 1、 HDFS 读写流程。 2、HDF…...

数据结构(C语言版)-6.查找

1. 查找的基本概念 2. 静态查找 2.1 顺序查找 typedef int KeyType; typedef int InfoType; typedef struct {KeyType key;InfoType otherdata; }SeqList; // 顺序表类型 // 顺序查找int SeqSearch(SeqList R[], int n, int k) {int i n;R[0].key k; // R[0].key为查找不成…...

RabbitMQ消息队列的笔记

Rabbit与Java相结合 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> 在配置文件中编写关于rabbitmq的配置 rabbitmq:host: 192.168.190.132 /…...

linux不同发行版中的主要差异

一、初始化系统 Linux不同发行版中的系统初始化系统&#xff08;如 System V init、Upstart 或 systemd&#xff09; System V init&#xff1a; 历史&#xff1a;System V init 是最传统的 Linux 系统初始化系统&#xff0c;起源于 Unix System V 操作系统。运行级别&#xff…...

Elasticsearch+Kibana分布式存储引擎

1.ElaticSearch介绍 ElaticSearch &#xff0c;简称为 ES &#xff0c; ES 是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检 索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理 PB 级别的数据。 ES 也使用 …...

spark 分布式 原理

Apache Spark 是一个快速且通用的大数据处理引擎&#xff0c;它支持分布式计算。Spark 的设计旨在通过高效的内存内计算和对多种数据源的支持来简化大规模数据集的处理。以下是关于 Spark 分布式原理的详细介绍&#xff1a; 1. 架构概述 Driver Program&#xff08;驱动程序&…...

Hadoop学习笔记(包括hadoop3.4.0集群安装)(黑马)

Hadoop学习笔记 0-前置章节-环境准备 0.1 环境介绍 配置环境&#xff1a;hadoop-3.4.0&#xff0c;jdk-8u171-linux-x64 0.2 VMware准备Linux虚拟机 0.2.1主机名、IP、SSH免密登录 1.配置固定IP地址&#xff08;root权限&#xff09; 开启master&#xff0c;修改主机名为…...

thinkphp:try-catch捕获异常

使用简单的例子&#xff0c;实现了一个简单的try-catch捕获异常的实例 //开始事务Db::startTrans(); try{ //有异常抛出异常 if(存在错误){ throw new \Exception("异常信息"); } // 提交事务 Db::commit(); // 返回成功信息 ... } catch (\…...

如何使用 uni-app 构建直播应用程序?

使用uni-app构建直播应用程序涉及前端和后端的开发&#xff0c;以及音视频处理技术的选择。下面我将概述一个典型的直播应用架构&#xff0c;并详细说明如何在uni-app中实现关键功能。 直播应用架构 前端&#xff08;uni-app&#xff09;&#xff1a;负责用户界面展示、互动逻…...