feat: TSPL

This commit is contained in:
陶林 2024-11-20 16:07:34 +08:00
parent 3c735d9643
commit 7b2c4cdd08
7 changed files with 100 additions and 3 deletions

BIN
output/avatar_average.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

File diff suppressed because one or more lines are too long

BIN
output/avatar_otsu.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

7
output/avatar_otsu.tspl Normal file

File diff suppressed because one or more lines are too long

View File

@ -3,8 +3,13 @@ import axios from 'axios';
import path from 'path';
import { mkdir } from 'fs/promises';
import { existsSync } from 'fs';
import { TSPLConverter } from './tsplConverter.js';
export class ImageProcessor {
constructor() {
this.tsplConverter = new TSPLConverter();
}
async downloadImage(url) {
try {
const response = await axios.get(url, { responseType: 'arraybuffer' });
@ -109,11 +114,17 @@ export class ImageProcessor {
.jpeg()
.toFile(outputPath);
// 生成 TSPL 指令并保存
const tsplCommands = this.tsplConverter.convertToTSPL(binaryData, info.width, info.height);
const tsplOutputPath = path.join(outputDir, `${baseName}${methodSuffix}.tspl`);
await this.tsplConverter.saveTSPLToFile(tsplCommands, tsplOutputPath);
return {
dimensions: { width: info.width, height: info.height },
threshold,
method,
outputPath
outputPath,
tsplPath: tsplOutputPath
};
} catch (error) {
throw new Error(`处理图片失败: ${error.message}`);

View File

@ -13,7 +13,8 @@ async function main() {
console.log('\nOTSU 处理结果:');
console.log(`图片尺寸: ${otsuResult.dimensions.width}x${otsuResult.dimensions.height}`);
console.log(`OTSU 阈值: ${otsuResult.threshold}`);
console.log(`输出路径: ${otsuResult.outputPath}`);
console.log(`图片输出路径: ${otsuResult.outputPath}`);
console.log(`TSPL 指令输出路径: ${otsuResult.tsplPath}`);
// 使用平均灰度方法处理
console.log('\n使用平均灰度方法处理图片:', imageUrl);
@ -21,7 +22,8 @@ async function main() {
console.log('\n平均灰度处理结果:');
console.log(`图片尺寸: ${avgResult.dimensions.width}x${avgResult.dimensions.height}`);
console.log(`平均灰度阈值: ${avgResult.threshold}`);
console.log(`输出路径: ${avgResult.outputPath}`);
console.log(`图片输出路径: ${avgResult.outputPath}`);
console.log(`TSPL 指令输出路径: ${avgResult.tsplPath}`);
} catch (error) {
console.error('程序执行失败:', error.message);

70
src/tsplConverter.js Normal file
View File

@ -0,0 +1,70 @@
import fs from 'fs/promises';
export class TSPLConverter {
constructor(options = {}) {
this.options = {
width: options.width || 384, // 打印宽度(点)
density: options.density || 8, // 打印浓度 (0-15)
speed: options.speed || 4, // 打印速度 (1-4)
...options
};
}
/**
* 将二值化图像数据转换为 TSPL 指令
* @param {Buffer} imageData - 二值化后的图像数据
* @param {number} width - 图像宽度
* @param {number} height - 图像高度
* @returns {string} TSPL 指令
*/
convertToTSPL(imageData, width, height) {
// TSPL 指令初始化
let tsplCommands = [];
// 清除缓冲区
tsplCommands.push('CLS');
// 设置标签大小和间隙
tsplCommands.push(`SIZE ${width} mm, ${height} mm`);
tsplCommands.push('GAP 0 mm, 0 mm');
// 设置打印浓度和速度
tsplCommands.push(`DENSITY ${this.options.density}`);
tsplCommands.push(`SPEED ${this.options.speed}`);
// 将图像数据转换为十六进制字符串
const hexData = this.convertImageDataToHex(imageData, width, height);
// BITMAP 命令格式x, y, width, height, mode, binary data
tsplCommands.push(`BITMAP 0, 0, ${width}, ${height}, 0, ${hexData}`);
// 打印命令
tsplCommands.push('PRINT 1');
return tsplCommands.join('\n');
}
/**
* 将图像数据转换为十六进制格式
*/
convertImageDataToHex(imageData, width, height) {
let hexString = '';
for (let i = 0; i < imageData.length; i++) {
const hex = (imageData[i] === 0 ? 1 : 0).toString(16);
hexString += hex.padStart(2, '0');
}
return hexString;
}
/**
* 保存 TSPL 指令到文件
*/
async saveTSPLToFile(tsplCommands, outputPath) {
try {
await fs.writeFile(outputPath, tsplCommands, 'utf8');
return outputPath;
} catch (error) {
throw new Error(`保存 TSPL 文件失败: ${error.message}`);
}
}
}