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

ESC/POS图片打印指令

一:实践前的理论部分

蓝牙/热敏打印机如何打印图片。

票据打印机的指令和条码打印机的指令对于打印图片的格式要求基本都相似

看看ESC/POS指令的文档

在这里插入图片描述
是的看不懂。。。干脆直接试试好了,从如何打印一个像素的小黑点开始。

注意到x的最小单位是字节数,而一个字节等于8个比特也就是说如果其实我能一次性控制8个点的打印
所以打印一个小黑点的指令就得出是:1D 76 30 00 01 00 01 00 80
如果想要八个点全黑,对应的指令是:1D 76 30 00 01 00 01 00 FF

我们能改变的最小单位也就是 80 和 FF

在这里插入图片描述

所以按这个公式理论上可以在一张小票纸上的任意位置打出黑点。

二、理论后的实践部分

实践:
从打印一个黑点开始,用到 get-pixels这个库可以获取到图片的宽高以及每个像素点的 rgba

仓库地址:https://github.com/scijs/get-pixels.git

1、打印一个黑点

getPixels('test/576.jpg',(err, { data, shape }) => {data = [0, 0, 0, 255]//这里直接赋值了一个黑点像素点的 rgba 信息shape = [1, 1, 4]//const imgData = rgba2hex(data, shape);const width = shape[0];const height = shape[1];const xL = Math.ceil((width / 8) % 256);  // 1const xH = Math.floor((width / 8) / 256); // 0const yL = height % 256; // 1const yH = Math.floor(height / 256); // 0const buffer = Buffer.from([0x1d, 0x76, 0x30, 0, xL, xH, yL, yH, ...imgData]);console.log("🚀 ~ getPixel ~ buffer:", buffer)//<Buffer 1d 76 30 00 01 00 01 00 80>const tenBuffer = blutoothEncode(buffer)console.log("🚀 ~ getPixels ~ tenBuffer:", tenBuffer.toString())
})

2、打印一排24个黑点

getPixels('test/576.jpg',(err, { data, shape }) => {data = [0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,]shape = [24, 1, 4]const imgData = rgba2hex(data, shape);const width = shape[0];const height = shape[1];const xL = Math.ceil((width / 8) % 256);  // 1const xH = Math.floor((width / 8) / 256); // 0const yL = height % 256; // 1const yH = Math.floor(height / 256); // 0const buffer = Buffer.from([0x1d, 0x76, 0x30, 0, xL, xH, yL, yH, ...imgData]);console.log("🚀 ~ getPixel ~ buffer:", buffer)//<Buffer 1d 76 30 00 01 00 01 00 80>const tenBuffer = blutoothEncode(buffer)console.log("🚀 ~ getPixels ~ tenBuffer:", tenBuffer.toString())
})

3、打印宽24,高8的黑点图

getPixels('test/576.jpg',(err, { data, shape }) => {data = [0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,0, 0, 0, 255,]shape = [24, 8, 4]const imgData = rgba2hex(data, shape);const width = shape[0];const height = shape[1];const xL = Math.ceil((width / 8) % 256);  // 1const xH = Math.floor((width / 8) / 256); // 0const yL = height % 256; // 1const yH = Math.floor(height / 256); // 0const buffer = Buffer.from([0x1d, 0x76, 0x30, 0, xL, xH, yL, yH, ...imgData]);console.log("🚀 ~ getPixel ~ buffer:", buffer)const tenBuffer = blutoothEncode(buffer)console.log("🚀 ~ getPixels ~ tenBuffer:", tenBuffer.toString())
})const rgba2hex = (data, shape) => {const bitArr = [];for (let i = 0; i < data.length; i = i + 4) {if (i[3] === 0) {bitArr.push(0);continue;}// 计算平均值判断const bit = (data[i] + data[i + 1] + data[i + 2]) / 3 > 160 ? 0 : 1;bitArr.push(bit);}// bitArr: [1]// 对bitArr做补0的动作let newBitArr = [];const width = shape[0];const isNeed = width % 8 !== 0;const height = shape[1];if (isNeed) {for (let i = 0; i < height; i++) {newBitArr.push(...bitArr.slice(i * width, (i + 1) * width));for (let j = 0; j < 8 - (width % 8); j++) {newBitArr.push(0);}}} else {newBitArr = bitArr;}// newBitArr: [1, 0, 0, 0, 0, 0, 0, 0]const byteArr = [];for (let i = 0; i < newBitArr.length; i = i + 8) {const byte =(newBitArr[i] << 7) +(newBitArr[i + 1] << 6) +(newBitArr[i + 2] << 5) +(newBitArr[i + 3] << 4) +(newBitArr[i + 4] << 3) +(newBitArr[i + 5] << 2) +(newBitArr[i + 6] << 1) +(newBitArr[i + 7]);byteArr.push(byte);}// byteArr: [128] = [0x80];return new Uint8Array(byteArr);
}/** 蓝牙十六进制指令 转换start */
const blutoothEncode = (buffer) => {let length = 0;buffer.forEach(item => {if (typeof item === "number") {length += 1;} else {length += item.length;}});const result = new Uint8Array(length);let index = 0;buffer.forEach(item => {if (typeof item === "number") {result[index] = item;index += 1;} else {result.set(item, index);index += item.length;}});// 取反码return handlePrintData(result);
}
// 处理打印机数据
function handlePrintData(arr) {let result = new Array(arr.length);for (let i = 0; i < arr.length; i++) {if (arr[i] < 128) {result[i] = arr[i];} else {// 减一let item = arr[i] - 1;// 反码let item2 = tenToTwo(item);let item3 = getReverseCode(item2);let item4 = twoToTen(item3);// 加上符号位result[i] = -item4;}}return result;
}
// 取反码
function getReverseCode(arr) {let result = [];for (let i = 0; i < arr.length; i++) {let item = arr[i];if (item === 1) {result.push(0);} else {result.push(1);}}return result;
}// 十进制转二进制
function tenToTwo(num) {let result = [];while (num > 0) {result.unshift(num % 2);num = Math.floor(num / 2);}return result;
}// 二进制转十进制
function twoToTen(arr) {let result = 0;for (let i = 0; i < arr.length; i++) {let item = arr[i];result += item * Math.pow(2, arr.length - i - 1);}return result;
}
/** 蓝牙十六进制指令 转换end */

十六进制的打印指令
getPixel ~ buffer: <Buffer 1d 76 30 00 03 00 08 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff>
十进制的打印指令
getPixels ~ tenBuffer: 29,118,48,0,3,0,8,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1

打印结果:

在这里插入图片描述

再测试打印一张图片:

在这里插入图片描述

三、实践结束理解图片打印指令

位图的基本概念?

位图: 是由许多像素点组成的图像表示方法。每个像素点都有其特定的颜色值或灰度值。
像素点: 是位图中的最小单位,每个像素点都有其特定的属性(如颜色、亮度等)。
字节存储:在打印指令中,位图数据通常以字节为单位进行存储和传输。

例如,在图中的xL、xH、yL、yH参数就是用于确定水平和垂直方向上的位图字节数和点数。

当打印机接收到包含位图数据的打印指令时,它会根据指令中的参数(如位图的大小、位置等)将位图数据转换为实际的打印输出。例如,指令中的xLxH确定了水平方向上的位图字节数,yLyH确定了垂直方向上的位图点数。打印机根据这些参数来安排位图在打印纸上的布局。

位图的分辨率(如纵向分辨率和横向分辨率)会影响打印输出的质量。在图中的指令格式中,不同的m值会选择不同的纵向和横向分辨率模式,从而影响位图在打印时的清晰度和大小。总之,位图在打印领域是一种重要的数据表示方式。

位图中像素点与字节、比特的关系?

在一般的位图表示中,一个像素点所占用的存储大小取决于位图的颜色深度。

黑白位图(1 - bit 位图)
如果是黑白位图,每个像素点只有两种状态:黑或白。这种情况下,一个像素点只需要 1 比特(1 bit)来表示。例如,0 可以表示白色,1 可以表示黑色。

灰度位图
对于灰度位图,如果有 256 级灰度,那么每个像素点需要 8 比特(1 字节,因为 1 字节 = 8 比特)来表示。这是因为 256 级灰度需要用 8 位二进制数(00000000 - 11111111)来区分不同的灰度级别。

彩色位图
在彩色位图中,情况更为复杂。例如,常见的 24 - bit 真彩色位图,每个像素点由红、绿、蓝(RGB)三个颜色通道组成,每个通道用 8 比特表示,所以一个像素点总共需要 24 比特(3 字节)来表示。

为什么 m 的取值范围有 2 个?

这个区间内的m值用于选择正常模式、倍宽模式、倍高模式和倍宽倍高模式。这些模式主要用于调整字符的宽度和高度。这个区间内的m值实际上是重复了 0 - 3 区间内的功能。这样设计可能是为了方便编程和指令的兼容性。这种设计使得在不同的编程环境或设备中,可以灵活地选择m值来实现相同的打印效果,提高了指令的通用性和易用性。

关于xL、xH、yL、yH的定义?

xL和xH:
xLxH表示水平方向位图字节数(xL + xH×256)。这里的xL是低字节xH是高字节。它们共同确定了水平方向上的位图字节数量。

例如,当xL + xH×256 = 64时,表示水平方向上有 64 个字节用于存储位图数据。

yL和yH:
yLyH表示垂直方向位图点数(yL + yH×256)。yL是低字节yH是高字节。它们共同确定了垂直方向上的位图点数。

例如,在图中的示例里,yL + yH×256表示垂直方向上的点数。

以水平方向为例,
如果xL = 1且xH = 0,那么水平方向位图字节数为1+0×256 = 1字节。
如果xL = 0且xH = 1,那么水平方向位图字节数为0 + 1×256=256字节。
在实际打印光栅位图时,通过这些参数可以准确地确定位图在纸张上的大小和位置,从而实现精确的打印输出。

字节顺序的概念?

在计算机中,数据常常以多个字节来存储。当一个数据需要用多个字节表示时,就存在字节顺序的问题。例如,一个 16 位的数据(在这个例子中类似xL + xH×256这样的数据)需要用两个字节来存储。
低字节(xL):指的是数据的低位部分。在数值表示中,它占的权重较小。
高字节(xH):指的是数据的高位部分。在数值表示中,它占的权重较大。

以xL + xH×256为例:

假设我们有一个水平方向位图字节数为 1000(十进制)。将 1000 转换为十六进制是03E8

在这种情况下:
低字节(xL):十六进制的E8(十进制的 232),这是低位部分。
高字节(xH):十六进制的03(十进制的 3),这是高位部分。

在 ESC/POS 指令中,当你看到xLxH这两个参数时,要知道它们组合起来表示一个较大的数值。xL总是代表低位部分,xH总是代表高位部分。在计算水平方向位图字节数时,就是按照xL + xH×256这样的公式来计算的。

到这里应该就比较清楚了类似 xL + xH×256 的式子就是在计算字节数的公式而已。

为什么 xL 等参数的取值范围是0 到 255?

在计算机中,一个字节(8 位)可以表示的数据范围是 0 - 255(十进制)。这是因为 8 位二进制数可以表示 个不同的值,从 00000000(十进制 0)到 11111111(十进制 255)。
xL、xH、yL、yH这些参数通常是用一个字节来存储的,所以它们的取值范围自然就限制在 0 - 255

对于大多数实际的打印应用场景,用一个字节来表示位图的大小或位置信息已经足够。常见的小票打印机或简单的标签打印机中,打印区域通常较小,不需要超过 255 个单位(字节数或点数)来表示位图的相关尺寸。如果超出这个范围,可能需要使用多个字节来表示更大的数值,但这会增加指令的复杂性和数据传输量。

总结

通过这个打印方式可以控制这张纸上能被热敏头接触到的任意地方都能打印出自己想要的信息,所以可以说是最好的打印方式。

缺点:从下发打印指令到打印机开始打印这个过程根据数据量的大小,会有不同程度的延迟,其次打印过程中并不能一次性的打完所有指令,会存在打一段停一段的情况,所以不适合大数据量的图片打印。

tip:某些打印机厂商的打印机没有好好实现规范于是按上述的图片指令打印方案图片高度超过一定程度就会出现乱码,需要把这张图片拆分成多张小图片才能正常打。

getPixels('test/576.jpg',(err, { data, shape }) => {const imgData = rgba2hex(data, shape);const width = shape[0];const height = shape[1];const xL = Math.ceil((width / 8) % 256);  // 1const xH = Math.floor((width / 8) / 256); // 0const yL = height % 256; // 1const yH = Math.floor(height / 256); // 0//const buffer = Buffer.from([0x1d, 0x76, 0x30, 0, xL, xH, yL, yH, ...imgData]);//const tenBuffer = blutoothEncode(buffer)//拆成小图const buffer = [];for(let i=0;i<height;i++) {let tempBuffer = [0x1d, 0x76, 0x30, 0, xL, xH, 1, 0, imgData.slice(i*(xL + 256*xH), (i+1)*(xL + 256*xH))]buffer[i] = tempBuffer;}
})

参考链接:
https://juejin.cn/post/7362537451170185252
https://juejin.cn/post/7297529039312158730
https://tech.youzan.com/retail-printer-picture

相关文章:

ESC/POS图片打印指令

一&#xff1a;实践前的理论部分 蓝牙/热敏打印机如何打印图片。 票据打印机的指令和条码打印机的指令对于打印图片的格式要求基本都相似 看看ESC/POS指令的文档 是的看不懂。。。干脆直接试试好了&#xff0c;从如何打印一个像素的小黑点开始。 注意到x的最小单位是字节数…...

Unity之如何在Linux上部署Dedicated Server专用服务器

文章目录 前言构建为专用服务器启动时获取参数在 DigitalOcean 上准备 Linux 服务器最后,让我们开始吧。前言 我们在使用Mirror,Fishnet或者Unity Netcode开发多人游戏时,一般有三种链接模式,分别是:Host,Server,Client。 Host:代表既是客户端又是服务器 Server:代表…...

十、Linux 故障排除专业案例分享

Linux 故障排除专业案例分享 在 Linux 操作系统漫长的使用历程当中&#xff0c;不可避免地会遭遇到各种各样不同类型的故障。本文将会深入而全面地阐述一些较为常见的 Linux 故障以及与之相对应的解决方案。其目的在于&#xff0c;当用户在实际使用过程中面临类似问题的时候&a…...

智慧楼宇平台,构筑未来智慧城市的基石

随着城市化进程的加速&#xff0c;城市面临着前所未有的挑战。人口密度的增加、资源的紧张、环境的恶化以及对高效能源管理的需求&#xff0c;都在推动着我们寻找更加智能、可持续的城市解决方案。智慧楼宇作为智慧城市建设的重要组成部分&#xff0c;正逐渐成为推动城市可持续…...

JVM 实战篇(一万字)

此笔记来至于 黑马程序员 内存调优 内存溢出和内存泄漏 内存泄漏&#xff08;memory leak&#xff09;&#xff1a;在Java中如果不再使用一个对象&#xff0c;但是该对象依然在 GC ROOT 的引用链上&#xff0c;这个对象就不会被垃圾回收器回收&#xff0c;这种情况就称之为内…...

线程同步之双摄

如何实现两个摄像头进行同步&#xff0c;并利用同步的信号做一些事情&#xff0c; 比如stereo camera 做深度&#xff0c;如果是自己整的两个camera&#xff0c;同步就需要自己做&#xff0c; 那么这时候可以利用线程同步手写一个&#xff0c;下面给一个示例代码&#xff1a; …...

使用 PyTorch 构建 LSTM 股票价格预测模型

目录 引言准备工作1. 训练模型&#xff08;train.py&#xff09;2. 模型定义&#xff08;model.py&#xff09;3. 测试模型和可视化&#xff08;test.py&#xff09;使用说明模型调整结论 引言 在金融领域&#xff0c;股票价格预测是一个重要且具有挑战性的任务。随着深度学习…...

【C++篇】C++类与对象深度解析(五):友元机制、内部类与匿名对象的讲解

文章目录 前言 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助&#xff01…...

模型训练进度条的代码

这个内容难在什么地方呢&#xff1f; 我想要跳转到另一个页面的时候 如何保存当前的训练状态&#xff0c;本来还想着加一个页面去管理进度的。然后想到了localstorage&#xff0c;将一些信息存储到浏览器中去。 进度条展示 <el-form-item label"训练进度" v-show…...

直观理解反向传播 | Chapter 3 | Deep Learning | 3Blue1Brown

目录 前言1. 简介2. 回顾3. 直观的演绎示例4. 随机梯度下降相关资料结语 前言 3Blue1Brown 视频笔记&#xff0c;仅供自己参考 这个章节主要来直观地理解反向传播算法到底在做什么 官网&#xff1a;https://www.3blue1brown.com 视频&#xff1a;https://www.bilibili.com/vide…...

052_python基于Python高校岗位招聘和分析平台

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…...

基于物联网、大数据、人工智能等技术开发的Spring Cloud 智慧工地云平台源码,支持多端应用

系统概述&#xff1a; 智慧工地是指运用现代信息技术&#xff0c;如物联网&#xff08;IoT&#xff09;、大数据、人工智能&#xff08;AI&#xff09;、云计算、移动互联网等&#xff0c;对传统建筑工地进行智能化改造和管理的新型工地。它通过高度集成的系统和设备&#xff…...

常见的跨境电商平台对比【总结表】

常见的跨境电商平台对比【总结表】 平台目标市场费用结构物流服务支付方式推广工具适合卖家亚马逊全球销售佣金、月租费、FBAFBA支持全球配送多种支付方式广告工具、促销活动有一定资金实力的品牌和卖家eBay全球上市费、成交费第三方物流支持PayPal、信用卡广告工具、促销活动…...

perl批量改文件后缀

perl批量改文件后缀 如题&#xff0c;perl批量改文件后缀&#xff0c;将已有的统一格式的文件后缀&#xff0c;修改为新的统一的文件后缀。 #!/bin/perl use 5.010;print "Please input file suffix which U want to rename!\n"; chomp (my $suffix_old <>)…...

【Python中的字符串处理】正则表达式与常用字符串操作技巧!

Python中的字符串处理&#xff1a;正则表达式与常用字符串操作技巧 Python 在字符串处理方面提供了丰富的内置功能和模块&#xff0c;能够帮助开发者处理各种复杂的文本操作。无论是简单的字符串拼接、替换&#xff0c;还是借助正则表达式&#xff08;re 模块&#xff09;实现…...

又是一年一度的1024,那就记录一篇算法博客吧~ 【二进制加法探秘】

前言&#xff1a; 又是一年一度的1024&#xff0c;那就记录一篇算法博客吧~ 内容如下~ 1 题目介绍 给定两个二进制字符串 a 和 b&#xff0c;需要返回它们的和&#xff0c;结果以二进制字符串形式给出。 示例 1&#xff1a; 输入: a “11”, b “1” 输出: “100” 示例 2…...

LeetCode--买卖股票的最佳时机含冷冻期--动态规划

一、题目解析 二、算法原理 我们可以使用dp[i]来表示第i天买卖股票所获得的最大利润。由题可得我们只能持有一支股票&#xff0c;并且在卖出后有冷冻期的限制&#xff0c;因此我们会有三种不同的状态&#xff1a; 我们目前持有一支股票&#xff0c;对应的「累计最大收益」记为…...

装了Ubuntu和Windows双系统,如何设置默认启动Windows

可以将默认启动系统设置为Windows&#xff0c;以下是步骤&#xff1a; 1. 修改GRUB配置文件&#xff1a; • 启动到Ubuntu&#xff0c;打开终端。 • 编辑GRUB配置文件&#xff1a; sudo nano /etc/default/grub • 找到这一行&#xff1a; GRUB_DEFAULT0 将0改为对应Wi…...

WPF+MVVM案例实战-设备状态LED灯变化实现

文章目录 1、项目创建2、UI界面布局1. MainWindow.xaml2、颜色转换器实现2.MainViewModel.cs 代码实现 3、运行效果4.源代码下载 1、项目创建 打开 VS2022 &#xff0c;新建项目 Wpf_Examples&#xff0c;创建各层级文件夹&#xff0c;安装 CommunityToolkit.Mvvm 和 Microsof…...

MySQL--基本介绍

一.数据库前言 1.数据库的相关介绍 关系数据库管理系统&#xff08;Relational Database Management System&#xff1a;RDBMS&#xff09;是指包括相互联系的逻辑组织和存取这些数据的一套程序 (数据库管理系统软件)。关系数据库管理系统就是管理关系数据库&#xff0c;并将数…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...