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

自定义webIpad证件相机(webRTC)

该技术方案可用于各浏览器自定义相机开发

相机UI(index.html)

<!DOCTYPE html>
<html lang="zh" prew="-1"><head><meta charset="UTF-8"><meta name="viewport"content="user-scalable=no, initial-scale=1, maximum-scale=5, minimum-scale=1, width=device-width" /><title>自定义相机</title><link rel="stylesheet" href="./style.css"><script src="./tools.js"></script><script src="./index.js"></script>
</head><body><div class="errTip"><p>Failed to obtain the rear camera of the device. Please try another solution to obtain resources!</p><button class="errBtn">GO Back</button></div><div class="takeOffTip"></div><div class="imgBoxDom"><div class="imgBox"><img src="./center.png" style="width: 4vw;"></div></div><div class="rightBtnBox"><div class="takeBtn"></div><div class="cancleBtn btn"></div></div><div class="bottomBtnBox"><div class="reTakeBtn btn bottonSize"></div><div class="nextBtn btn bottonSize"></div></div><div class="loading-css">Loading...</div>
</body></html>

 相机UI样式(style.css)

* {margin: 0;padding: 0;box-sizing: border-box;border: 0;
}html,
body {width: 100%;height: 100%;overflow: hidden;background-color: #000;color: #fff;
}.cancleBtn {padding: 2vw 0;width: 100%;
}.takeOffTip {position: fixed;padding-top: 2vw;top: 0;left: 0;width: 100%;font-size: 1.8vw;text-align: center;color: #fff;
}.bottonSize {height: 100%;line-height: 6vw;line-height: 6dvw;padding: 0 1.5vw;
}.bottomBtnBox,
.rightBtnBox {position: fixed;right: 0;display: flex;justify-content: space-between;align-items: center;background-color: #000;z-index: 10;
}.bottomBtnBox {bottom: 0;width: 100%;height: 6vw;height: 6dvw;
}.rightBtnBox {flex-direction: column;top: 0;height: 100%;width: 6vw;width: 6dvw;
}html[prew='-1'] .bottomBtnBox,
html[prew='0'] .bottomBtnBox,
html[prew='-1'] .rightBtnBox,
html[prew='1'] .rightBtnBox,
html[prew='1'] .customer_carema {display: none;
}html[prew='1'] .imgBox {border: 0;font-size: 0;opacity: 0;
}.takeBtn {padding: 4px;width: 5vw;width: 5dvw;height: 5vw;height: 5dvw;background-color: #fff;border-radius: 50%;
}.takeBtn::before {content: '';display: block;width: 100%;height: 100%;border: 5px solid #000;background-color: #fff;border-radius: 50%;box-sizing: border-box;
}.rightBtnBox::before {content: '';display: block;
}.btn {background-color: #000;text-align: center;font-size: 1.5vw;color: #fff;
}.customer_video,
.carema_img,
.cuteImg {width: 100%;height: 100%;object-fit: cover;
}.imgBoxDom {position: fixed;top: 0;left: 0;width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;z-index: 9;
}.imgBox {width: var(--carema-box-width);height: var(--carema-box-height);border: 2px solid #fff;display: flex;justify-content: center;align-items: center;font-size: 10vw;z-index: 10;border-radius: 2vw;
}.errTip {position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: 8888;display: none;flex-direction: column;justify-content: center;align-items: center;background-color: #000;
}.errTip>p {padding-bottom: 20px;color: #fff;
}.errTip button {padding: 10px 30px;
}html[prew='2'] .errTip {display: flex;
}html[loaded='1'] .loading-css {display: none;
}.loading-css {position: fixed;top: 0;left: 0;width: 100%;height: 100%;display: flex;flex-direction: column;justify-content: center;align-items: center;background-color: #000;z-index: 9999;
}.loading-css::before {margin-bottom: 10px;content: '';width: 50px;height: 50px;display: inline-block;border: 3px solid #f3f3f3;border-top: 3px solid rgb(160, 155, 155);border-radius: 50%;animation: loading-360 0.8s infinite linear;
}@keyframes loading-360 {0% {transform: rotate(0deg);}100% {transform: rotate(360deg);}
}

调试UI(carema.html)
 

<!DOCTYPE html>
<html lang="zh"><head><meta charset="UTF-8"><meta name="viewport"content="user-scalable=no, initial-scale=1, maximum-scale=5, minimum-scale=1, width=device-width" /><title>调试相机</title><style>* {margin: 0;padding: 0;box-sizing: border-box;border: 0;}img {max-width: 100%;}.btnList {padding: 10px;}label[type='file'],button {padding: 0 10px;height: 32px;line-height: 32px;display: inline-block;font-size: 14px;appearance: auto;border: 1px solid #999;background-color: #dcdcdc;}label>input {font-size: 0;width: 0;height: 0;overflow: hidden;}.showImg {padding: 5px;display: flex;flex-wrap: wrap;}.showImg>.box {width: 33.33%;padding: 5px;}.showImg>.box>.img {width: 100%;height: 20vw;overflow: hidden;border-radius: 10px;border: 2px solid #888;}.showImg>.box>.img>img {width: 100%;height: 100%;object-fit: cover;}html,body {height: 100%;height: 100%;}body {display: flex;flex-direction: column;}.showImg {flex: 1;overflow-x: hidden;}</style>
</head><body><div class="btnList"><button onclick="openCarema('HK_ID')">COMM_ID_IMG</button><button onclick="openCarema('LANDING')">LANDING_IMG</button><label name="upload" type="file">LOCAL_IMG<input type="file" id="upload"></label></div><div class="showImg" id="showImg"></div>
</body>
<script>function fileToBase64(file) {return new Promise((resolve, reject) => {// 创建一个新的 FileReader 对象var reader = new FileReader();// 读取 File 对象reader.readAsDataURL(file);// 加载完成后reader.onload = function () {// 将读取的数据转换为 base64 编码的字符串var base64String = reader.result.split(",")[1];// 解析为 Promise 对象,并返回 base64 编码的字符串resolve(base64String);};// 加载失败时reader.onerror = function () {reject(new Error("Failed to load file"));};});}function showImg(url) {var showImgDom = document.getElementById('showImg');var img = document.createElement('img');img.src = `data:image/jpeg;base64,${url}`;var div = document.createElement('div');var cDiv = document.createElement('div');div.append(cDiv);cDiv.append(img);div.className = 'box';cDiv.className = "img";showImgDom.insertBefore(div, showImgDom.firstChild);}document.getElementById('upload').addEventListener('change', function ($event) {var file = $event.target.files[0];fileToBase64(file).then(showImg);})function openCarema(idType) {var openId = Date.now() + '';window.open(`./index.html?openId=${openId}&idType=${idType}&isDev=1`);window.addEventListener('message', function (res) {var resOpenId = res.data.openId;var mothod = res.data.mothod;var file = res.data.imgUrl;console.log(resOpenId, mothod, file);if (mothod === "success_file" && openId === resOpenId) fileToBase64(file).then(showImg);})}
</script></html>

相机逻辑基础(index.js)

function WbCRM() {this.body = document.body;this.html = document.documentElement;this.takeBtn = document.querySelector('.takeBtn');this.imgBox = document.querySelector('.imgBox');this.reTakeBtn = document.querySelector('.reTakeBtn');this.cancleBtn = document.querySelector('.cancleBtn');this.nextBtn = document.querySelector('.nextBtn');var errBtn = document.querySelector('.errBtn');this.video = null;this.err = null;this.fullImg = null;this.file = '';this.idType = '';this.isDev = false;this.stream = null;this.openId = '';this.ratio = window.devicePixelRatio || 1;this.videoWidth = this.body.clientWidth * this.ratio;this.videoHeight = this.body.clientHeight * this.ratio;this.html.setAttribute('prew', '-1');var isMp3 = !(navigator.userAgent.match(/Firefox/));var audio = new Audio();audio.autoplay = isMp3 ? './shutter.mp3' : './shutter.ogg';this.audio = audio;console.log(isMp3,audio);this.mediaDevices = (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ?navigator.mediaDevices : ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? {getUserMedia: function (c) {return new Promise(function (y, n) {(navigator.mozGetUserMedia ||navigator.webkitGetUserMedia).call(navigator, c, y, n);});}} : null);this.setDom();this.setCarema();this.takeBtn.addEventListener('click', this.takePhoto.bind(this));this.nextBtn.addEventListener('click', this.next.bind(this));this.reTakeBtn.addEventListener('click', this.reTake.bind(this));this.cancleBtn.addEventListener('click', this.cancle.bind(this));errBtn.addEventListener('click', this.openErro.bind(this));
}
WbCRM.prototype.openErro = function () {this.sendMsg('open_erro');
}
WbCRM.prototype.cancle = function () {this.removeStream();this.sendMsg('off_carema');
}
WbCRM.prototype.next = function () {if (this.fullImg) this.fullImg.remove();this.removeStream();this.sendMsg('success_file');
}
WbCRM.prototype.reTake = function () {this.file = null;this.err = null;if (this.fullImg) this.fullImg.remove();this.html.setAttribute('loaded', 0);this.removeStream();this.setCarema();
}
WbCRM.prototype.cutImage = function () {var boxWidth = this.imgBox.clientWidth * this.ratio;var boxHeight = this.imgBox.clientHeight * this.ratio;var vLeft = (this.videoWidth - boxWidth) / 2;var vTop = (this.videoHeight - boxHeight) / 2;var nCanvas = wbCRMTools.drawHighDefinitionImg(boxWidth, boxHeight);var nCtx = nCanvas.getContext('2d');nCtx.drawImage(this.fullImg, -vLeft, -vTop);var cutImage = nCtx.getImageData(0, 0, boxWidth, boxHeight);wbCRMTools.changeImgData(cutImage?.data || [], this.idType || '');nCtx.putImageData(cutImage, 0, 0);reImgUrl = nCanvas.toDataURL('image/jpeg');var cImg = document.createElement('img');cImg.src = reImgUrl;this.file = wbCRMTools.canvas2File(reImgUrl);wbCRMTools.clearCanvas(nCtx, nCanvas);cImg.className = "cuteImg";this.imgBox.append(cImg);this.html.setAttribute('prew', '1');this.removeStream();
}
WbCRM.prototype.takePhoto = function () {var gCanvas = wbCRMTools.drawHighDefinitionImg(this.videoWidth, this.videoHeight);var originalCtx = gCanvas.getContext('2d');originalCtx.drawImage(this.video, 0, 0, this.videoWidth, this.videoHeight);var imgUrl = gCanvas.toDataURL('image/jpeg');var fullImg = document.createElement("img");fullImg.className = "carema_img";fullImg.src = imgUrl;this.fullImg = fullImg;this.body.append(fullImg);wbCRMTools.clearCanvas(originalCtx, gCanvas);this.audio.play();fullImg.onload = this.cutImage.bind(this);
}WbCRM.prototype.sendMsg = function (mothod) {this.audio.remove();const origin = this.isDev ? undefined : window.location.origin;window.opener.postMessage({ mothod: mothod, file: this.file, openId: this.openId, error: this.err }, origin);window.close();
}WbCRM.prototype.removeStream = function () {var self = this;if (self.stream) {self.stream.getTracks().forEach(function (track) {if (track.readyState === 'live') track.stop();self.stream.removeTrack(track);});}if (this.video) this.video.remove();var cuteImgList = document.querySelectorAll('.cuteImg');cuteImgList.forEach(function (dom) {dom.remove();})
}WbCRM.prototype.setDom = function () {this.openId = wbCRMTools.getUrlParam('openId');var okText = wbCRMTools.getUrlParam('continue');var cancelText = wbCRMTools.getUrlParam('cancel');var retakeText = wbCRMTools.getUrlParam('retake');var idType = wbCRMTools.getUrlParam('idType') || '';var takeOffTip = wbCRMTools.getUrlParam('takeOffTip');const isDev = wbCRMTools.getUrlParam('isDev');this.isDev = isDev === '1';this.nextBtn.innerText = okText || 'Cuntinue';this.cancleBtn.innerText = cancelText || 'Cancel';this.reTakeBtn.innerText = retakeText || 'Retake';document.querySelector('.takeOffTip').innerHTML = takeOffTip;this.html.setAttribute('loaded', 0);this.html.style.setProperty('--carema-box-width', '64.512vw');this.html.style.setProperty('--carema-box-height', '40.6789vw');if (idType === "LANDING") {this.html.style.setProperty('--carema-box-width', '51.2vw');this.html.style.setProperty('--carema-box-height', '44.5935vw');}this.idType = idType;
}WbCRM.prototype.setVideo = function (stream) {var video = document.createElement('video');video.setAttribute('autoplay', 'autoplay');video.setAttribute('playsinline', 'playsinline');video.className = 'customer_video';this.video = video;this.stream = stream;this.body.append(video);var self = this;video.onloadedmetadata = function (e) {self.stream = stream;self.loaded = true;self.html.setAttribute('loaded', 1);};video.onplay = function () {self.html.setAttribute('prew', '0');}// as window.URL.createObjectURL() is deprecated, adding a check so that it works in Safari.// older browsers may not have srcObjectif ("srcObject" in video) {video.srcObject = stream;} else {// using URL.createObjectURL() as fallback for old browsersvideo.src = window.URL.createObjectURL(stream);}
}WbCRM.prototype.setCarema = function () {const videoConf = this.isDev ? {} : {width: { min: 1024, ideal: 2360, max: 2732 },height: { min: 776, ideal: 1640, max: 2048 },facingMode: { exact: "environment" }}var self = this;this.mediaDevices.getUserMedia({audio: false,video: videoConf}).then(this.setVideo.bind(this)).catch(function (error) {self.err = error.toString();self.html.setAttribute('prew', '2');self.html.setAttribute('loaded', '1');})
}window.addEventListener('load', function () {var wbCRM = new WbCRM();window.addEventListener('visibilitychange', function () {wbCRM.removeStream();window.close();});
});

图片出路和文件生成工具(tools.js) 

var wbCRMTools = {drawHighDefinitionImg: function (width, height) {const canvas = document.createElement('canvas');canvas.style.width = width + 'px';canvas.style.height = height + 'px';canvas.width = width;canvas.height = height;return canvas;},clearCanvas: function (ctx, canvas) {ctx.clearRect(0, 0, canvas.width, canvas.height);ctx.beginPath();canvas.height = 0;canvas.width = 0;canvas.remove();canvas.parentNode?.removeChild(canvas);},changeImgData: function (data, idType) {const isGrayscale = ['PASSPORT', 'LANDING', 'ENTRYPERMIT', 'SUP_LEGAL_ID'].some(imgType => idType.indexOf(imgType) !== -1);let contrast = 35;const thereshold = 20;if ('LANDING' === idType) contrast = 45;// gaussBlur will use in the feature, cancel this fun now, don`t delete please// this.gaussBlur(imageData, 1);// If MacId and HK-LANDING change cavans-img-code.const factor = (255 + contrast) / (255.01 - contrast);  //add .1 to avoid /0 errorconst denominator = 1 / (1 - contrast / 255) - 1;const setCV = cv => cv + (cv - thereshold) * denominator;const setCTV = cv => cv + (cv - thereshold) * contrast / 255;const getRGB = cv => factor * (cv - 128) + 128;// Data array data-length.const len = data?.length || 0;// loop value to change cavans imgData;for (let index = 0; index < len; index += 4) {let R = data[index];     //r valuelet G = data[index + 1]; //g valuelet B = data[index + 2] //b valueif (contrast || thereshold) {R = getRGB(R); //r valueG = getRGB(G); //g valueB = getRGB(B); //b value}const isColorNum = index % 4 === 0;if (isColorNum) {R = contrast ? setCV(R) : setCTV(R);G = contrast ? setCV(G) : setCTV(G);B = contrast ? setCV(B) : setCTV(B);if (isGrayscale) {const vNum = Math.round((R + G + B) / 3);R = vNum;G = vNum;B = vNum;data[index + 3] = 255;}data[index] = R;data[index + 1] = G;data[index + 2] = B;}}},getUrlParam: function (urlKey) {var url = window.location.search;var reg = new RegExp("(^|&)" + urlKey + "=([^&]*)(&|$)");var result = url.substring(1).match(reg);return result ? decodeURIComponent(result[2]) : null;},canvas2File: function (dataUrl) {let arr = dataUrl.split(','),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}const nowId = Date.now();const fileName = `takePhoto_${nowId}.jpeg`;const blob = new Blob([u8arr], { type: mime, name: fileName });blob.lastModifiedDate = new Date();return new File([blob], fileName, { type: "image/jpeg" });}
}

 文件目录

效果图

相关文章:

自定义webIpad证件相机(webRTC)

该技术方案可用于各浏览器自定义相机开发 相机UI&#xff08;index.html&#xff09; <!DOCTYPE html> <html lang"zh" prew"-1"><head><meta charset"UTF-8"><meta name"viewport"content"user-sc…...

GO发票真伪批量查验方法、数电票查验接口

“教”给机器标注数据的正确率就决定了人工智能判断的正确率。翔云人工智能开放平台的OCR产品经过我们的开发人员精心调“教”&#xff0c;识别率高、识别速度快。 发票&#xff0c;是发生的成本、费用或收入的原始凭证。于公司来说&#xff0c;发票主要是公司做账的依据&…...

【Go系列】Go的UI框架Fyne

前言 总有人说Go语言是一门后端编程语言。 Go虽然能够很好地处理后端开发&#xff0c;但是者不代表它没有UI库&#xff0c;不能做GUI&#xff0c;我们一起来看看Go怎么来画UI吧。 正文 Go语言由于其简洁的语法、高效的性能和跨平台的编译能力&#xff0c;非常适合用于开发GUI…...

.NET MAUI:跨平台开发的未来

常用资源 &#xff08;1&#xff09;.NET MAUI8构建应用文档。 Build your first .NET MAUI app - .NET MAUI | Microsoft Learn 一、什么是 .NET MAUI&#xff1f; .NET Multi-platform App UI (.NET MAUI) 是微软推出的一款跨平台开发框架。作为 Xamarin.Forms 的下一代产…...

VSCode切换默认终端

我的VSCode默认终端为PowerShell&#xff0c;每次新建都会自动打开PowerShell。但是我想让每次都变为cmd&#xff0c;也就是Command Prompt 更改默认终端的操作方法如下&#xff1a; 键盘调出命令面板&#xff08;CtrlShiftP&#xff09;中,输入Terminal: Select Default Prof…...

卫星观测叶绿素的相反信号

Contrasted Trends in Chlorophyll-a Satellite Products 运用卫星产品研究Chl的长时间序列变化时需要注意 Introduction &#xff08;1&#xff09;研究叶绿素的长期变化&#xff0c;需要至少40年的长时间序列&#xff1b; &#xff08;2&#xff09;Tian and Zhang 2023报告…...

2024年最新NVIDIA T4价格表及行业趋势!

英伟达&#xff08;NVIDIA&#xff09;作为目前全球T0级别的GPU制造商&#xff0c;其T4系列显卡以其卓越的计算性能和能效比&#xff0c;在数据中心、云计算及AI领域占据重要地位。 一、NVIDIA T4价格表概览 在探讨NVIDIA T4显卡的价格时&#xff0c;我们需要从直接购买和租赁…...

HTML + CSS编程规范

编程规范 HTML CSS 命名规范 HTML CSS 命名规范 1. 命名需要是具备语义性的单词&#xff0c;不能用 数字 拼音 数字,符号开头正确示范 &#xff1a; wrap description title content错误示范 : aaaa a1 $we 4tdds 2. 命名需要多个单词连接的情况下, 标记语言中可以使用 …...

机器学习之人脸识别-使用 scikit-learn 和人工神经网络进行高效人脸识别

文章摘要 本文将介绍如何使用 Python 的 scikit-learn 库和人工神经网络&#xff08;ANN&#xff09;来识别人脸。我们将使用 LFW 数据集&#xff08;Labeled Faces in the Wild&#xff09;&#xff0c;这是一个广泛用于人脸识别基准测试的大型人脸数据库。我们将展示如何准备…...

【虚拟化】KVM概念和架构

目录 一、什么是KVM&#xff1f; 二、KVM的功能 2.1 主要的功能 2.2 其它功能 三、KVM核心组件及作用 四、KVM与VMware的优势 五、KVM架构 六、qemu介绍 七、创建虚拟机流程 一、什么是KVM&#xff1f; Kernel-based Virtual Machine的简称&#xff0c;KVM 是基于虚拟…...

【Linux】权限2

Linux文件要被执行满足两个条件: ①必须要具备可执行权限 x ②真的是一个可执行程序 1.权限的修改,文件强行给别人 权限就是拦住一批人,不让他做特定的一件事情 a.更改人,更改文件所隶属的人 如果把文件强行给别人, chown xxx(普通用户) xxx(文件名) 会出现下面的情况 很明显…...

汽车长翅膀:GPU 是如何加速深度学习模型的训练和推理过程的?

编者按&#xff1a;深度学习的飞速发展离不开硬件技术的突破&#xff0c;而 GPU 的崛起无疑是其中最大的推力之一。但你是否曾好奇过&#xff0c;为何一行简单的“.to(‘cuda’)”代码就能让模型的训练速度突飞猛进&#xff1f;本文正是为解答这个疑问而作。 作者以独特的视角&…...

怀旧必玩!重返童年,扫雷游戏再度登场!

Python提供了一个标准的GUI&#xff08;图形用户界面&#xff09;工具包&#xff1a;Tkinter。它可以用来创建各种窗口、按钮、标签、文本框等图形界面组件。 而且Tkinter 是 Python 自带的库&#xff0c;无需额外安装。 Now&#xff0c;让我们一起来回味一下扫雷小游戏吧 扫…...

Avalonia中的路由事件

文章目录 一、路由事件的基本概念事件路由机制事件的生命周期二、创建路由事件定义路由事件触发路由事件处理路由事件三、使用路由事件的场景用户输入控件交互动画和样式数据绑定和验证四、路由事件的优缺点优点:缺点:五、总结在Avalonia中,路由事件是处理用户交互和控件之间…...

ubuntu20.04安装RabbitMQ +Erlang

ubuntu20.04安装RabbitMQ 3.11.19Erlang 25.3.1_ubuntu20.04.6 安装 rabbitmq-CSDN博客 LINUX下载编译libpng_linux libpng下载-CSDN博客 Ubuntu20.04 安装 Nginx 软件报错&#xff1a;libgd3 缺少 libpng12-0 依赖 Ubuntu安装RabbitMq&#xff08;保姆级教学&#xff0c;直…...

【word转pdf】【最新版本jar】Java使用aspose-words实现word文档转pdf

【aspose-words-22.12-jdk17.jar】word文档转pdf 前置工作1、下载依赖2、安装依赖到本地仓库 项目1、配置pom.xml2、配置许可码文件&#xff08;不配置会有水印&#xff09;3、工具类4、效果 踩坑1、pdf乱码2、word中带有图片转换 前置工作 1、下载依赖 通过百度网盘分享的文…...

分布式:RocketMQ/Kafka总结(附下载链接)

文章目录 下载链接思维导图 本文总结的是关于消息队列的常见知识总结。消息队列和分布式系统息息相关&#xff0c;因此这里就将消息队列放到分布式中一并进行处理关联 下载链接 链接: https://pan.baidu.com/s/1hRTh7rSesikisgRUO2GBpA?pwdutgp 提取码: utgp 思维导图...

Air780EP模块 LuatOS开发-MQTT接入阿里云应用指南

简介 本文简单讲述了利用LuatOS-Air进行二次开发&#xff0c;采用一型一密、一机一密两种方式认证方式连接阿里云。整体结构如图 关联文档和使用工具&#xff1a;LuatOS库阿里云平台 准备工作 Air780EP_全IO开发板一套&#xff0c;包括天线SIM卡&#xff0c;USB线 PC电脑&…...

【算法】插入区间

难度&#xff1a;中等 题目&#xff1a; 给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInte…...

C++ 代码实现socket 类使用TCP/IP进行通信 (windows 系统)

C 代码实现socket 类使用TCP/IP进行通信 &#xff08;windows 系统&#xff09; TCP客户端通信常规步骤&#xff1a; 1.初始换socket环境 2.socket()创建TCP套接字。 3.connect()建立到达服务器的连接。 4.与客户端进行通信&#xff0c;recv()/send()接受/发送信息&#xff0…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...