hiprint打印/jsPDF使用/html2canvas

最初我知道hiprint.print是可以打印双模板的,于是查看hiprint.print的源码发现底层实现是this.getHtml(t).hiwprint,于是断点查看getHtm的实现,得知它是遍历我们对print传参的list,利用list中模板对象的getHtml()方法得到模板的dom对象,同时利用append将两个模板dom拼接到一个模板对象里然后返回。至此我们可以拿到一个合成的模板对象,这个对象可以拿到对应的dom节点,于是查看hiwprint实现,发现它其实创建一个iframe标签然后,把之前生成的dom对象直接利用innerHTML直接赋值给iframe里的contentWindow的body的子节点,然后调用浏览器原生打印方法去打印,于是想着手写一个hiwprint2方法模仿创建一个iframe然后赋值dom,赋值成功,但是两个模板dom重叠了,于是研究原生print生成的iframe对象,发现在head标签中比我们多了两个样式,于是在源码基础上手动拼上这个样式的link,然后就成功显示了两个dom,接着我就想使用html2tocanvas结合jsPDF生成破地方,但是遇到一个问题,那就是我们写的hiwprint2的代码里是获取不到iframe里对象dom的(获取的好像不是原生对象,需要在研究确定下是不是真不能获取),考虑是不是需要使用插入script标签字符串代码的形式,觉得太麻烦就不用此办法了!,后续想到我们生成的dom不放在iframe不就行了,遂写一个dom节点A,然后把getHtml()生成的节点利用innerHtml的形式赋值给A,至此,我们双模板生成的dom可以显示在我们创建的A上,于是接着研究如何利用html2tocanvas把dom生成图片,然后在转成base64放到pdf里,这里遇到了分页的问题,以及利用jsPDF 创建的pdf对象的addImage方法(用于将图片会知道pdf中)绘制时,图片的高度不是A5对应的比例,遂调整addImage的 imgWidth, imgHeight 两个入参,这些都解决后就剩一个我们利用html2tocanvas生成的pdf中的二维码是放大的,于是有想到hiprintTrmp.toPdf生成的base64里二维码是好的,于是查看源码,仔细研究发现.toPdf里调用了svg2canvas,遂断点查看,发现svg2canvas该函数又调用canvg,百度得知canvg是用于把svg转为canvas的库,于是在代码里加上svg2canvas函数,发现加上后一直不生效,有点怀疑人生,百度了好久,最后还是对比源码中svg2canvas的带调用和我们的调用有什么不同,无果好几次,最后时刻发现源码里的u.html(l[0]),而我们在tocanvas后好像没有新的dom重新解析,而是直接html()拿到dom节点,然后赋值给hiprintDom的innerHTML属性,于是重新对dom节点使用html函数。

当不传参数时,.html() 方法返回匹配元素的 HTML 内容,当传入一个参数时,.html(htmlString) 会将匹配的元素的 HTML 内容替换为指定的 htmlString。所有匹配的元素都会被更新,且旧内容将被替换

A4纸张中的长宽比例约为1.412, new jsPDF 的参数landscape,对于A4和A5的方向不同的,简记:那个轴上纸张长哪个轴就是纵向的,(从一张A4切割成A5纸张容易误导,)

Node中的Buffer 和 TypeArray,ArrayBuff

在这里插入图片描述
构造函数new Buffer()的第一个参数可以是一个Number,Array或String。第二个参数为可选参数,用来表示encode的类型,可以是AscII, Utf8, Ucs2, Base64, Binary, Hex。默认值是Utf8。

Electron的核心是由Chromium和Node.js组成,‌其中Chromium负责渲染和显示Web页面,‌而Node.js则提供了主进程的功能,‌包括管理应用程序的生命周期、‌创建和控制浏览器窗口以及与操作系统交互。‌通过嵌入Chromium和Node.js到二进制文件中,‌Electron使得开发者能够保持JavaScript代码库的一致性,‌从而轻松地创建跨平台的应用程序,‌而无需具备本地开发经验。‌

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。
Base64,就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+“、”/"一共64个字符的字符集,(任何符号都可以转换成这个字符集中的字符,这个转换过程就叫做base64编码。[2]
Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

我们常说的分辨率指的是设备独立像素, 一般情况下,独立像素比指的是 物理像素与设备独立像素的比值,如果计算出来的物理像素大于实际物理像素,手机会自动页面缩放系数指的是css像素/设备独立像素

随着手机的发展,不管分辨率多高,他们所展示的界面比例都是基本类似的,所以我们必须使用一种单位来同时告诉不同分辨率的手机,他们再界面上显示元素的大小是多少,这个单位就是设备独立像素,简称DIP或者DP,打开chrome开发工具,我们模拟各个手机型号的显示情况,iphoneX显示为 375x812,这里显示的就是独立像素比,所以我们设计稿一般指的也是独立像素比

window.devicePixelRatio 为啥是浏览器的缩放系数 只有web下是指的缩放系数,浏览器上chrome调试手机指的就是

2k屏幕理解,缩放比为100%时候,由于我们使用的是px,就是独立像素,当缩放比从200%变为为100%时候,1px/1独立像素实际对用的 “屏幕尺寸更小了(一个css像素跨越更少的物理像素)”,相当于“css像素更小了”

因为缩放系数指的是 css像素/设备独立像素。缩放系数为1时候,1css像素等于1设备独立像素。

hiprint 是如何把mm转为html里的px的?

Node中的Buffer 和 TypeArray,ArrayBuffer, Unit8Array

在看 Node 的 Buffer 模块文档时, 文档中提到这么一段话

Buffer实例也是Uint8Array实例。 但是与ECMAScript 2015中的 TypedArray 规范还是有些微妙的不同。 例如,当ArrayBuffer#slice()创建一个切片的副本时,Buffer#slice()的实现是在现有的Buffer上不经过拷贝直接进行创建,这也使得Buffer#slice()更高效
其中提到了 Unit8Array, TypedArray 以及 ArrayBuffer 这些类, 因此就想弄明白这些概念之间的关系是怎样的, 在看了 ES6的文档以及 Buffer 源代码后, 总算是理解了一些

TypedArray

首先要弄清楚 TypedArray 的概念, 这是 ES2015(又称ES6) 中新出的一个接口, 不能直接被实例化, 也就是说如下代码会报错.

new TypedArray()
因为这个接口就是一个抽象接口, 就像java中的抽象接口一样, 是不能被实例化的, 只能实例化实现该接口的子类. Uint8Array 就是实现 TypedArray 接口的一个子类.

就Nodejs而言, 可以使用Buffer操作二进制数据, 那对前端JS而言, 在 TypeArray 出现之前, 是没有可以直接操作二进制数据的类的, 这也与前端很少需要操作二进制数据相关.

所以 TypeArray 接口的作用是操作二进制数据.

TypeArray 是一个类数组结构, 也就是说数组可以用的函数, 比如 arr[0], slice, copy 等方法, TypeArray也可以使用.

ArrayBuffer

TypedArray 的作用是操作二进制数据, 其内部还有一个buffer属性, 这个buffer就是 ArrayBuffer 实例. ArrayBuffer 就存储了要操作的二进制数据.

因此可以知道, TypedArray 是一个操作二进制数据的接口, 内部的 ArrayBuffer 存储了要操作的二进制数据.

Unit8Array

实现了 TypedArray 接口的子类有很多, Unit8Array 就是其中一个, 这个子类表示: 数组中的每一个元素都是 8个二进制位(1个字节)的无符号整数.

无符号的含义是, 该二进制的首位不表示符号位. 而对于有符号的二进制位, 首位1表示负数. 如下实例:

二进制表示 10001111 00001111
无符号 143 15
有符号 -15(首位1表示负数) 15

所以 Unit8Array 中每个元素的取值范围应该是 0 ~ 255.

实现 TypedArray 接口的子类还有:

Int8Array: 每个元素是8个二进制位(1个字节)的有符号整数
Uint8Array: 每个元素是8个二进制位(1个字节)的无符号整数
Int16Array: 每个元素是16个二进制位(2个字节)的有符号整数
Uint16Array:每个元素是16个二进制位(2个字节)的无符号整数
Int32Array: 每个元素是32个二进制位(4个字节)的有符号整数
Uint32Array: 每个元素是32个二进制位(4个字节)的无符号整数

所以可以想到, 对于 Int8Array, 每个元素的取值范围应该是 -127 ~ 127.

对于3个元素的 Uint16Array 对象, 对应的字节长度为 3 * 2 = 6 个字节.

如下图:

TypedArray类型 要存储的数据16进制表示 数组长度 内部buffer(假设大端序存储)

Unit8Array 0x01 0x02 0x04 0x08 4(每个元素1字节) Buffer<0x01 0x02 0x04 0x08>(4字节)

Uint16Array 0x01 0x02 0x04 0x08 2(每个元素2字节) Buffer<0x01 0x02 0x04 0x08>(4字节)

Uint32Array 0x01 0x02 0x04 0x08 1(每个元素4字节) Buffer<0x01 0x02 0x04 0x08>(4字节)
存储同一个二进制数据, 使用三种 TypedArray 去存储, 内部 buffer 存储的数据都是一样的, 均占据4个字节(因为大端序和小端序会对字节存储顺序有影响, 这里假设都是大端序存储), 但是每种 TypedArray 外在表现的数组长度却是不一样的.

Buffer

最后就要提到 Buffer 这个类, Buffer 在前端JS中并不存在, 是 Node 专门提供用来操作二进制数据的, 因为对于后端来说, 操作二进制数据是比较基础的操作.

而在 ES6 的 TypeArray 推出之后, 自 Node 3.0.0 版本开始, Buffer 继承自 Unit8Array, 相当于是对 ES6 中的 TypeArray 做兼容.

那么到目前为止, 这些概念应该都很清楚了:

TypedArray: ES6 提供的用来操作二进制数据的接口, 具体由子类实现.

ArrayBuffer: 在 TypedArray 内部, 存储了要操作的二进制数据.

Unit8array: 实现 TypedArray, 每个元素都占据一个字节.

Buffer: Node中才有, 继承自 Unit8array, 拥有更多强大的二进制数据操作.

Buffer API 文档中提到的疑惑点解释
在弄明白 Unit8Array, TypedArray 以及 ArrayBuffer 和 Buffer 之间的相互关系后, 我们现在对 Buffer API 官方文档中提到的内容和一些示例做一些解释.

官方代码示例1:

// https://www.nodeapp.cn/buffer.html#buffer_buffers_and_typedarray
const arr = new Uint16Array(2);

arr[0] = 5000; 
arr[1] = 4000;

// 拷贝 `arr` 的内容
const buf1 = Buffer.from(arr);

// 与 `arr` 共享内存
const buf2 = Buffer.from(arr.buffer);

// 输出: <Buffer 88 a0>
console.log(buf1);

// 输出: <Buffer 88 13 a0 0f>
console.log(buf2);

这段代码仔细分析的话是存在几个疑惑点的,我们先看下 5000 和 4000的不同进制表示:

数字 二进制 16进制
5000 0001 0011 1000 1000 13 88
4000 0000 1111 1010 0000 0f a0

1.对于buf2而言, 为何打印的是 <Buffer 88 13 a0 0f> 而不是 <Buffer 13 88 0f a0> 呢 ?

对于buf1而言, 为何长度是2而不是4, 打印的是 <Buffer 88 a0> 而不是 <Buffer 88 13> 呢?
对于第一个问题, 比较简单, 因为 Uint16Array 存储数据时使用的是小端序, 也就是每个元素中的字节顺序要反过来.

13 88 使用小端序存储时, 显示为 88 13

13 88 使用大端序存储时, 显示为 13 88

tip:关于大端序和小断序, 百度可以搜到很多讲解, 这里不细说.

因此, 打印的结果是 <Buffer 88 13 a0 0f>.

对于第二个问题, 我们必须得查看下Buffer的源码,

// https://github.com/nodejs/node/blob/v10.x/lib/buffer.js
from 函数 -> fromObject 函数 -> fromArrayLike 函数
function fromArrayLike(obj) { // 在我们的例子中, 这里obj就是 Uint16Array 对象
  const length = obj.length; // 得到新buffer的长度
  const b = allocate(length);
  for (var i = 0; i < length; i++)
    b[i] = obj[i]; // 设置buffer每个字节对应的数值 b[0] = 5000  b[1] = 4000
  return b;
}

}
可以看到 const length = obj.length; 这段代码, 获取的是 Uint16Array 对象的长度, 而不是 Uint16Array 对象内部 BufferArray 的长度, 所以最终返回的 buffer 的长度是2.

b[i]= obj[i]; 则是设置 buffer 每个字节的值, 那么根据这段设置, 返回的 buffer 中的元素应该是 [5000, 4000] 呀.

实际上, 对于Buffer对象而言, 每个字节的取值范围是在0~ 255 之间(想一下, Buffer继承自 Unit8Array), 对于 > 255的数, 不断减少256, 直到最终值在 0~ 255 之间, 对于 < 0 的数, 不断增加256, 直到最终值在 0~ 255 之间

tip: 如果看过深入浅出node.js , 应该知道里面也提过Buffer中每个元素的取值计算

所以:

b[0] = 5000 => b[0] = 5000 % 256 = 136 对应16进制表示为 88

b[0] = 4000 => b[1] = 4000 % 256 = 160 对应16进制表示为 a0

那么第二个问题也弄清楚了, Buffer.from(TypedArray), 返回的新buffer长度就是TypedArray的长度, buffer中每个字节值就是 TypedArray中每个元素经过计算后的值.

注意,Buffer模块会预分配一个大小为Buffer.poolSize的内部Buffer实例作为快速分配池, 用于使用Buffer.allocUnsafe()新创建的Buffer实例,以及废弃的new Buffer(size)构造器, 仅限于当size小于或等于Buffer.poolSize >> 1(Buffer.poolSize除以2后的最大整数值

也就是说 只有使用 Buffer.allocUnsafe() 和废弃的 new Buffer 创建buffer对象时, 如果buffer的大小小于4KB, 则使用内部的Buffer实例作为快速分配池, 而不是申请新的内存.

如果看过朴灵的 深入浅出node.js, 就会知道文章中也这么提到过:

为了高效的使用分配的内存,Node采用了slab分配机制。如果指定的Buffer的大小小于8KB, 那么Node就会按照小对象的方式进行分配, 不为该buffer申请新的内存, 而是直接使用分配池中的内存.

两者的描述基本都一致, 不过深入浅出node.js 这本书推出时, 还是使用的 new Buffer 创建buffer对象, 不过自Node5.10.0开始, 因为安全性, 使用 new Buffer 创建buffer的方式已经弃用了, 取而代之的是使用 from, alloc 和 allocUnsafe 等函数来创建buffer对象,

tip: 具体可查看翻译的文档 Porting to Buffer.from()/Buffer.alloc() API

快速分配池这种方式理解起来蛮简单的:

就是一个buffer长度小于4KB时, 直接使用内部一个Buffer的内存, 因此, 会存在几个buffer对象的parent都是同一个对象这种情况, 如下来自深入浅出node.js的截图:

空的快速分配池

分配一个1024 bit (128Byte)的buffer1

分配一个4000 bit (500Byte)的buffer2
buffer1 和 buffer 2 的 parent 都指向同一个快速分配池

当然, 现在弃用了buffer.parent的叫法, 改为了buffer.buffer.

TypedArray中的buffer属性就是 BufferArray对象, Unit8Array 实现了 TypedArray, Buffer又继承自 Unit8Array,所以 buffer.buffer 就是一个 ArrayBuffer对象.

直接看下 Buffer 源码中的 allocUnsafe函数, 验证下文档内容:

// https://github.com/nodejs/node/blob/68a6b8d3751bcaa96f32bdb843f171a098f1cbdb/lib/buffer.js#L79
// allocUnsafe => allocate
function allocate(size) {
  if (size <= 0) {
    return new FastBuffer();
  }
  if (size < (Buffer.poolSize >>> 1)) { // Buffer.poolSize 默认 = 8KB
    if (size > (poolSize - poolOffset)) // 快速分配池大小 - 快速分配池已分配的内存[添加链接描述](https://www.nodeapp.cn/buffer.html#buffer_class_method_buffer_allocunsafe_size)
      createPool(); // 快速分配池剩下空间不足时, 创建新的快速分配池
    var b = new FastBuffer(allocPool, poolOffset, size); // 使用快速分配池的内存
    poolOffset += size; // 更新快速分配池以分配的内存
    alignPool();
    return b;
  } else {
    return createUnsafeBuffer(size); // 不适用快速分配池
  }
}

代码所显示的逻辑和文档中提到的一致

参考:

深入浅出node.js

Node官方文档 Buffer

TypedArray

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

干货 | Selenium+chrome自动批量下载地理空间数据云影像

1.背景介绍 1.1地理空间数据云 由中国科学院计算机网络信息中心科学数据中心成立的地理空间数据云平台是常见的下载空间数据的平台之一。其提供了较为完善的公开数据&#xff0c;如LANDSAT系列数据&#xff0c;MODIS的标准产品及其合成产品&#xff0c;DEM数据&#xff08;SR…

NVIDIA驱动学习

lspci | grep -i vga 输出&#xff1a; 2d:00.0 VGA compatible controller: NVIDIA Corporation Device 2204 (rev a1) 99:00.0 VGA compatible controller: NVIDIA Corporation Device 2230 (rev a1)import torch print(torch.version.cuda) # 应该显示 CUDA 版本 print(tor…

【自动化与控制系统】SCI一区TOP神刊!最快19天accept、稳定检索!

期刊解析 &#x1f6a9;本 期 期 刊 看 点 &#x1f6a9; 国人发文占比第一&#xff0c;TOP刊 审稿友好&#xff0c;审稿速度快 自引率9.8% 今天小编带来计算机领域SCI快刊的解读&#xff01; 如有相关领域作者有意投稿&#xff0c;可作为重点关注&#xff01; 01 期刊信息…

综合评价 | 基于熵权-变异系数-博弈组合法的综合评价模型(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 根据信息熵的定义&#xff0c;对于某项指标&#xff0c;可以用熵值来判断某个指标的离散程度&#xff0c;其信息熵值越小&#xff0c;指标的离散程度越大&#xff0c; 该指标对综合评价的影响&#xff08;即权重&…

鸿蒙开发(API 12 Beta6版)【HCE卡模拟开发】 网络篇

简介 近场通信(Near Field Communication&#xff0c;NFC)是一种短距高频的无线电技术&#xff0c;在13.56MHz频率运行&#xff0c;通信距离一般在10厘米距离内。HCE(Host Card Emulation)&#xff0c;称为基于主机的卡模拟&#xff0c;表示不依赖安全单元芯片&#xff0c;电子…

辽宁汇聚公益慈善力量,绿葆网络助力辽宁绿色生态建设,彰显企业大爱

9月5日&#xff0c;于辽宁省沈阳市隆重举行的“中华慈善日”主题宣传活动暨“山海有情 天辽地宁”即开型福利彩票发行、“生态公益林”项目启动仪式上&#xff0c;广州绿葆网络发展有限公司作为受邀企业之一&#xff0c;积极履行社会责任&#xff0c;向辽宁省慈善联合总会捐赠了…

Python教程(二十) : 十分钟入门【PyQt6】

文章目录 专栏列表环境准备1 安装 Python2 安装 PyQt6 创建 PyQt6 项目1 创建项目目录2 创建主 Python 文件 代码书写测试流程1 导入 PyQt6 模块2 创建主窗口类3 创建应用程序实例并运行 核心解析&#xff1a;PyQt6 中的模块示例代码&#xff1a; PyQt6 常用的控件1. QPushButt…

如何选适合混合云环境下的监控系统?

在选择适合混合云环境下的监控系统时&#xff0c;需要考虑以下几个关键因素&#xff1a; 1. 兼容性 跨平台支持&#xff1a;确保监控系统能够无缝地在私有云、公有云和本地环境中运行。 API集成&#xff1a;支持与各种云服务提供商的API集成&#xff0c;以便收集来自不同来源的…

算法知识点————双指针【删除重复元素】【反转链表】

删除重复元素 题目&#xff1a;//给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数 思路&#xff1a…

基于微信小程序的机票预订平台的设计与实现的设计与实现---附源码80729

摘要 本文介绍了一个基于微信小程序的机票预订平台的设计与实现。随着移动互联网的快速发展&#xff0c;用户对机票预订的需求日益增长&#xff0c;因此开发一个便捷、高效的机票预订平台变得尤为重要。 本文首先分析了机票预订平台的背景和需求&#xff0c;然后详细阐述了系统…

计算机毕业设计选题推荐-班级管理系统-教务管理系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

网络基础入门指南(一)

前言 在这个高度互联的世界里&#xff0c;互联网已成为日常生活不可或缺的一部分。然而&#xff0c;对于许多人来说&#xff0c;网络是如何工作的仍然是个谜。本文旨在为那些对网络基础知识感兴趣的朋友提供一个简单的介绍&#xff0c;帮助大家更好地理解互联网的基本原理和技…

远程搜索:remote-method

为了启用远程搜索&#xff0c;需要将filterable和remote设置为true&#xff0c;同时传入一个remote-method。remote-method为一个Function&#xff0c;它会在输入值发生变化时调用&#xff0c;参数为当前输入值。需要注意的是&#xff0c;如果el-option是通过v-for指令渲染出来…

【C++ Qt day9】

2、将day1做的登录界面升级优化【资源文件的添加】 3、 使用手动连接&#xff0c;将登录框中的取消按钮使用第2种方式的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上…

elementui Cascader 级联选择器的使用总结

实现效果 技术要点总结如下&#xff1a; 1、点击添加自动增加多行&#xff0c;实现自主选择增加多条节点数据 2、节点地址使用的是Cascader 级联选择器&#xff0c;需要动态生成&#xff0c;涉及到一个技术要点是&#xff1a;因v-modal只能获取value不能获取label&#xff0c;故…

CCF编程能力等级认证GESP—C++7级—20240907

CCF编程能力等级认证GESP—C1级真题 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09;判断题&#xff08;每题 2 分&#xff0c;共 20 分&#xff09;编程题 (每题 25 分&#xff0c;共 50 分)小杨寻宝矩阵移动 单选题&#xff08;每题 2 分&#xff0c;共 30 分&…

网络安全工程师(白帽子)企业级学习路线

第一阶段&#xff1a;安全基础&#xff08;入门&#xff09; 第二阶段&#xff1a;Web渗透&#xff08;初级网安工程师&#xff09; 第三阶段&#xff1a;进阶部分&#xff08;中级网络安全工程师&#xff09;

数据分析-14-时间序列异常检测的六类常用方法(案例实战)

1 异常值检测的六类方法 异常值检测与处理是数据清洗过程中的一个关键步骤,它涉及到识别和处理那些与大多数数据显著不同的数据点。异常值可能是由于数据录入错误、测量误差、数据损坏或其他原因造成的。处理异常值的目的是提高数据的质量,避免它们对分析结果产生不利影响。…

关于领英的干货文章

今天这篇文章是关于领英的干货文章 没有用领英还有已经在用的朋友记得点赞哦&#xff0c; 这样需要的时候才能找到“我” 从这几个点出发 linkedln的注册&#xff0c;资料信息设置linkedin 发布动态linkedin 加人linkedin 加群客户开发 注册及资料信息设置 注册linkedin新…

无人驾驶遇上‘超级WiFi‘,低速无人驾驶已成为了主要趋势?

嘿,各位工业大佬们!今天咱们来聊个又酷又实用的话题 - 工业无人驾驶!不过,别以为这只是在工厂里溜达溜达的小推车,我们要聊的可是能在矿山里"跑酷"的大家伙! 想象一下,在一个尘土飞扬的露天矿场,几辆庞大的无人卡车正在有条不紊地工作。它们像是被施了魔法一样,自动…