自定义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" });}
}

 文件目录

效果图

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

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

相关文章

Llama 3.1要来啦?!测试性能战胜GPT-4o

哎呀&#xff0c;Meta声称将于今晚发布的Llama 3.1&#xff0c;数小时前就在Hugging Face上泄露出来了&#xff1f;泄露的人很有可能是Meta员工&#xff1f; 还是先来看泄露出来的llama3.1吧。新的Llama 3.1模型包括8B、70B、405B三个版本。 而经过网友测试&#xff0c;该base…

Spark实时(二):StructuredStreaming编程模型

文章目录 StructuredStreaming编程模型 一、基础语义 二、事件时间和延迟数据 三、​​​​​​​​​​​​​​容错语义 StructuredStreaming编程模型 一、基础语义 Structured Streaming处理实时数据思想是将实时数据看成一张没有边界的表&#xff0c;数据源源不断的追…

年化22.8%的单因子分析:基于Alphalens做可转债全市场数据的单因子分析(附python代码+全量数据)

原创文章第597篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 因子分析是量化研究的基本技能之一。通过因子分析&#xff0c;找出有效的因子&#xff0c;通过相关性去重后&#xff0c;就可以通过机器学习、线性回归等方法把因子组合起来&#xf…

Linux基础学习day1

1.Linux系统介绍 1.常见的操作系统 1.Windows&#xff08;NT内核&#xff09;不开源 2.ubantu&#xff08;linux内核&#xff09; 3.ios&#xff08;unix内核&#xff09;不开源 4.鸿蒙&#xff08;兼容linux内核&#xff09; 5.Android&#xff08;linux内核&#xff09…

STM32(七):STM32指南者-通信实验

目录 一、基本概念通讯基本概念1、串行和并行2、同步通讯与异步通讯3、全双工、半双工、单工4、通讯速率 USART基本概念1、串口通讯基本概念2、物理层3、协议层4、指南者的串口USART I2C基本概念SPI基本概念 二、USART串口实验前期准备1、安装安装 USB 转串口驱动_CH3402、野火…

Git之repo sync -l与repo forall -c git checkout用法区别(四十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

微信各平台历史版本含下载地址大全( 安卓 | Windows | MAC )

微信-windows-版本历史 https://github.com/tom-snow/wechat-windows-versions/releases 微信-windows-x86版本历史 https://github.com/tom-snow/wechat-windows-versions-x86/releases 微信安卓版本历史 https://github.com/DJB-Developer/wechat-android-history-version…

Apache DolphinScheduler 3.2.2 版本正式发布!

Apache DolphinScheduler 3.2.2 版本正式发布&#xff01; 近日&#xff0c;Apache DolphinScheduler 发布了 3.2.2 版本。此版本主要基于 3.2.1 版本进行了 bug 修复&#xff0c;新增若干特性&#xff0c;并进行了众多改进和 Bug 修复&#xff0c;以及文档修复等。 &#x1…

电路学习——经典运放电路之滞回比较器(施密特触发器)(2024.07.18)

参考链接1: 电子设计教程29&#xff1a;滞回比较器&#xff08;施密特触发器&#xff09; 参考链接2: 滞回比较器电路详细分析 参考链接3: 比较器精髓&#xff1a;施密特触发器&#xff0c;正反馈的妙用 参考链接4: 比较器反馈电阻选多大&#xff1f;理解滞后效应&#xff0c;轻…

【iOS】进程与多线程

目录 前言进程和线程进程和线程的区别多线程的意义时间片概念 线程的生命周期线程池的运行策略自旋锁和互斥锁自旋锁互斥锁自旋锁和互斥锁区别原子属性 iOS多线程技术方案 前言 学习此文&#xff1a;iOS多线程 在平时的iOS开发中&#xff0c;多线程是我们常会遇到的&#xff0…

新手教学系列——如何在MacOS 10.13.6(老系统)手动安装和配置Pyenv

前言 对于使用老旧系统&#xff08;如MacOS 10.13.6&#xff09;的用户来说&#xff0c;安装和管理Python版本可能会遇到一些挑战。特别是由于Homebrew不再支持老系统&#xff0c;许多软件安装变得困难重重。本文将详细介绍如何在这样的环境下手动安装和配置Pyenv&#xff0c;…

BGP选路之Next Hop

原理概述 当一台BGP路由器中存在多条去往同一目标网络的BGP路由时&#xff0c;BGP协议会对这些BGP路由的属性进行比较,以确定出去往该目标网络的最优BGP路由,然后将该最优BGP路由与去往同一目标网络的其他协议路由进行比较&#xff0c;从而决定是否将该最优BGP路由放进P路由表中…

数据代理实践

1&#xff0c;什么事数据代理机制&#xff1f; 通过访问 代理对象的属性 来向该访问 目标对象的属性 数据代理机制的视线需要依靠&#xff0c;Object.defineProperty()方法 2&#xff0c; ES6新特性&#xff1a; 在对象中的函数/方法 &#xff1a;function是可以省略的 &l…

宝塔国际版Docker Manager 3.4获取镜像列表报错解决办法

宝塔国际版安装Docker Manager 3.4,遇到获取镜像列表的时候报错。 解决办法 找到:/www/server/panel/plugin/docker/docker_main.py文件 替换函数utc_to_local 原代码 # UTC时间转换为时间戳def utc_to_local(self, utc_time_str, utc_format=%Y-%m-%dT%H:%M:%S):

机器学习(五) -- 无监督学习(1) --聚类2

系列文章目录及链接 上篇&#xff1a;机器学习&#xff08;五&#xff09; -- 无监督学习&#xff08;1&#xff09; --聚类1 下篇&#xff1a; 前言 tips&#xff1a;标题前有“***”的内容为补充内容&#xff0c;是给好奇心重的宝宝看的&#xff0c;可自行跳过。文章内容被…

2个案例区分是平行眼还是交叉眼,以及平行眼学习方法

案例一&#xff1a; 交叉眼&#xff1a;看到凸出的“灌水”&#xff0c;是交叉眼。PS&#xff1a;看的时候&#xff0c;眼是斗鸡眼&#xff0c;眼睛易疲劳 平行眼&#xff1a;看到凹陷的“灌水”&#xff0c;是平行眼。PS&#xff1a;看的时候眼睛是平视&#xff0c;不容易疲…

springboot校园车辆管理系统-计算机毕业设计源码63557

校园车辆管理系统 摘 要 校园车辆管理系统是当前高校校园管理中的一个重要方面&#xff0c;其有效管理和调度对于提升校园的运行效率和管理水平至关重要。本论文基于Spring Boot框架开发了一套校园车辆管理系统&#xff0c;系统主要包括用户和管理员两大角色&#xff0c;涵盖…

Sprint Boot 2 核心功能(二)

数据访问 1、SQL 1.1、数据源的自动配置-HiKariDataSource 1.1.1、导入JDBC场景 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency>数据库驱动&#xff1…

什么是湖仓一体?湖仓一体解决了什么问题?

目录 一、数据仓库&数据湖&湖仓一体概念辨析 1.数据仓库&#xff08;Data Warehouse&#xff09; 2.数据湖&#xff08;Data Lake&#xff09; 3.湖仓一体&#xff08;Lakehouse&#xff09; 二、湖仓一体的优点 三、湖仓一体要解决什么问题? 四、结语 随着当前大数据…

在spyder中使用arcgis pro的包

历时2天终于搞定了 目标&#xff1a;在anconda中新建一个arcpyPro环境&#xff0c;配置arcgispro3.0中的arcpy 一、安装arcgispro3.0 如果安装完之后打开arcgispro3.0闪退&#xff0c;就去修改注册表&#xff08;在另一台电脑安装arcgispro遇到过&#xff09; 安装成功后可…