Files
APP/components/TextToHex/textToDotMatrixFor7305.vue
2025-10-31 15:35:03 +08:00

204 lines
5.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<canvas canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
class="offscreen-canvas"></canvas>
</view>
</template>
<script>
export default {
name: "textToDotMatrixFor7305",
props: {
txts: {
type: Array,
default: () => [],
validator: (value) => value.every(item => typeof item === 'string')
},
fontSize: {
type: Number,
default: 16,
validator: (value) => value > 0 && value <= 100
},
bgColor: {
type: String,
default: "#ffffff"
},
color: {
type: String,
default: "#000000"
}
},
data() {
return {
// 当前Canvas的宽高动态调整
currentCanvasWidth: 0,
currentCanvasHeight: 0,
// Canvas上下文复用
ctx: null
};
},
computed: {
validTxts() {
return this.txts.filter(line => line.trim() !== '');
}
},
mounted() {
// 初始化Canvas上下文只创建一次
this.ctx = uni.createCanvasContext('reusableCanvas', this);
},
methods: {
/**
* 估算单行文本所需的Canvas宽度
*/
calcLineWidth(textLine) {
return textLine.length * this.fontSize;
},
/**
* 清除Canvas内容
*/
clearCanvas() {
this.ctx.setFillStyle(this.bgColor);
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
},
/**
* 复用单个Canvas处理所有文本行
*/
async drawAndGetPixels() {
let binaryToHex = (binaryArray) => {
if (!Array.isArray(binaryArray) || binaryArray.length !== 8) {
throw new Error("输入必须是包含8个元素的二进制数组");
}
// 检查每个元素是否为0或1
if (!binaryArray.every(bit => bit === 0 || bit === 1)) {
throw new Error("数组元素必须只能是0或1");
}
// 将二进制数组转换为十进制数
let decimalValue = 0;
for (let i = 0; i < 8; i++) {
// 计算每个位的权重并累加
decimalValue += binaryArray[i] * Math.pow(2, 7 - i);
}
// 将十进制转换为十六进制字符串并添加0x前缀
const hexString = "0x" + decimalValue.toString(16).padStart(2, '0').toUpperCase();
return hexString;
}
let convertCharToMatrix = (imageData, item) => {
const charWidth = 13;
const charHeight = 12;
const pixels = [];
for (let i = 0; i < imageData.length; i += 4) {
const R = imageData[i];
pixels.push(R < 128 ? 1 : 0);
}
const lowBytes = new Array(charWidth).fill(0);
const highBytes = new Array(charWidth).fill(0);
for (let col = 0; col < charWidth; col++) {
for (let row = 0; row < charHeight; row++) {
const pixel = pixels[row * charWidth + col];
if (pixel === 1) {
if (row < 8) {
lowBytes[col] |= (1 << row);
} else {
highBytes[col] |= (1 << (row - 8));
}
}
}
}
return [...lowBytes, ...highBytes];
}
let drawTxt = async (textLine) => {
let result = {};
let ctx = this.ctx;
// 1. 动态调整Canvas尺寸
this.currentCanvasWidth = 13;
this.currentCanvasHeight = 12;
// 2. 清空Canvas绘制背景
this.clearCanvas();
// 3. 设置文字样式
ctx.setFillStyle(this.color);
ctx.setTextBaseline('middle');
// ctx.setTextAlign('center')
ctx.setFontSize(this.fontSize);
ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
// 4. 绘制当前行文本
let currentX = 0;
let currentY = this.fontSize / 2 + 1;
for (let j = 0; j < textLine.length; j++) {
let char = textLine[j];
ctx.fillText(char, currentX, currentY);
// 按实际字符宽度计算间距
let charWidth = ctx.measureText(char).width;
currentX += charWidth;
}
// 5. 异步绘制并获取像素数据(串行处理避免冲突)
await new Promise((resolve, reject) => {
ctx.draw(false, () => {
uni.canvasGetImageData({
canvasId: 'reusableCanvas',
x: 0,
y: 0,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight,
success: res => {
result = {
line: textLine,
pixelData: res.data,
width: this.currentCanvasWidth,
height: this.currentCanvasHeight
};
resolve();
},
fail: err => {
// console.error(`处理第${i+1}行失败:`, err);
reject(err)
}
});
});
});
return result;
}
let arr = [];
// 循环处理每行文本
for (let i = 0; i < this.validTxts.length; i++) {
let linePixls = [];
let item = this.validTxts[i];
// console.log("item=", item);
for (var j = 0; j < item.length; j++) {
let result = await drawTxt(item[j]);
linePixls.push(convertCharToMatrix(result.pixelData, item));
}
// console.log("hexs=", linePixls.join(","));
arr.push(linePixls);
}
return arr;
}
}
};
</script>
<style>
.offscreen-canvas {
position: fixed;
left: -9999px;
top: -9999px;
}
</style>