feat: TSPL
This commit is contained in:
parent
3c735d9643
commit
7b2c4cdd08
BIN
output/avatar_average.jpg
Normal file
BIN
output/avatar_average.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
7
output/avatar_average.tspl
Normal file
7
output/avatar_average.tspl
Normal file
File diff suppressed because one or more lines are too long
BIN
output/avatar_otsu.jpg
Normal file
BIN
output/avatar_otsu.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
7
output/avatar_otsu.tspl
Normal file
7
output/avatar_otsu.tspl
Normal file
File diff suppressed because one or more lines are too long
@ -3,8 +3,13 @@ import axios from 'axios';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { mkdir } from 'fs/promises';
|
import { mkdir } from 'fs/promises';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
|
import { TSPLConverter } from './tsplConverter.js';
|
||||||
|
|
||||||
export class ImageProcessor {
|
export class ImageProcessor {
|
||||||
|
constructor() {
|
||||||
|
this.tsplConverter = new TSPLConverter();
|
||||||
|
}
|
||||||
|
|
||||||
async downloadImage(url) {
|
async downloadImage(url) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
const response = await axios.get(url, { responseType: 'arraybuffer' });
|
||||||
@ -109,11 +114,17 @@ export class ImageProcessor {
|
|||||||
.jpeg()
|
.jpeg()
|
||||||
.toFile(outputPath);
|
.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 {
|
return {
|
||||||
dimensions: { width: info.width, height: info.height },
|
dimensions: { width: info.width, height: info.height },
|
||||||
threshold,
|
threshold,
|
||||||
method,
|
method,
|
||||||
outputPath
|
outputPath,
|
||||||
|
tsplPath: tsplOutputPath
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(`处理图片失败: ${error.message}`);
|
throw new Error(`处理图片失败: ${error.message}`);
|
||||||
|
@ -13,7 +13,8 @@ async function main() {
|
|||||||
console.log('\nOTSU 处理结果:');
|
console.log('\nOTSU 处理结果:');
|
||||||
console.log(`图片尺寸: ${otsuResult.dimensions.width}x${otsuResult.dimensions.height}`);
|
console.log(`图片尺寸: ${otsuResult.dimensions.width}x${otsuResult.dimensions.height}`);
|
||||||
console.log(`OTSU 阈值: ${otsuResult.threshold}`);
|
console.log(`OTSU 阈值: ${otsuResult.threshold}`);
|
||||||
console.log(`输出路径: ${otsuResult.outputPath}`);
|
console.log(`图片输出路径: ${otsuResult.outputPath}`);
|
||||||
|
console.log(`TSPL 指令输出路径: ${otsuResult.tsplPath}`);
|
||||||
|
|
||||||
// 使用平均灰度方法处理
|
// 使用平均灰度方法处理
|
||||||
console.log('\n使用平均灰度方法处理图片:', imageUrl);
|
console.log('\n使用平均灰度方法处理图片:', imageUrl);
|
||||||
@ -21,7 +22,8 @@ async function main() {
|
|||||||
console.log('\n平均灰度处理结果:');
|
console.log('\n平均灰度处理结果:');
|
||||||
console.log(`图片尺寸: ${avgResult.dimensions.width}x${avgResult.dimensions.height}`);
|
console.log(`图片尺寸: ${avgResult.dimensions.width}x${avgResult.dimensions.height}`);
|
||||||
console.log(`平均灰度阈值: ${avgResult.threshold}`);
|
console.log(`平均灰度阈值: ${avgResult.threshold}`);
|
||||||
console.log(`输出路径: ${avgResult.outputPath}`);
|
console.log(`图片输出路径: ${avgResult.outputPath}`);
|
||||||
|
console.log(`TSPL 指令输出路径: ${avgResult.tsplPath}`);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('程序执行失败:', error.message);
|
console.error('程序执行失败:', error.message);
|
||||||
|
70
src/tsplConverter.js
Normal file
70
src/tsplConverter.js
Normal 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}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user