Commit 6dfcf308 by linjinhong

fix:修改原来问题

parent f5d555aa
......@@ -570,117 +570,74 @@ const FIXED_MASK_RATIO = {
};
async function cropToPrintArea(inputPath, outputPath, data) {
let RATIO;
if (!data) return false;
// 1. 解构数据
// -------- 你原来的解构(我修正 drawImage 来源)--------
const { canvasWidth, canvasHeight, rect_info, drawImage } = data;
// 注意:list 里可能有多张图,这里默认取第一张进行裁剪
// 如果你的业务逻辑需要对特定图层裁剪,需要根据业务调整这里的选择逻辑
// drawImage 结构: [dx, dy, dWidth, dHeight] (画布坐标系)
const [dx, dy, imgRenderW, imgRenderH] = drawImage;
try {
// 2. 获取原图尺寸
const meta = await sharp(inputPath).metadata();
const realW = meta.width;
const realH = meta.height;
// 3. 核心计算逻辑:坐标映射
// 3.1 计算图片的缩放比例 (渲染尺寸 / 原图尺寸)
// 注意:如果前端有旋转,这里需要更复杂的计算,但你说不考虑旋转
const scaleX = imgRenderW / realW;
const scaleY = imgRenderH / realH;
// 3.2 计算 rect_info 在画布上相对于图片左上角的偏移量
// 公式:画布上的坐标 - 图片在画布上的偏移
// 结果:画布上的打印区域相对于图片渲染内容的位置
const relX = rect_info.leftDistance - dx;
const relY = rect_info.topDistance - dy;
// 3.3 将相对偏移映射回原图坐标系
// 公式:画布上的相对位置 / 缩放比例
let cropX = Math.round(relX / scaleX);
let cropY = Math.round(relY / scaleY);
// 3.4 计算裁剪框的宽高 (同样需要映射回原图尺寸)
// 注意:rect_info 的宽高是画布上的像素宽高,需要除以缩放比例得到原图像素宽高
let cropW = Math.round(rect_info.rectWidth / scaleX);
let cropH = Math.round(rect_info.rectHeight / scaleY);
// 4. 安全边界处理 (非常重要)
// 因为图片可能没有完全覆盖打印区域(比如用户把图片缩小了,或者拖到了一边),
// 计算出来的 cropX/cropY 可能是负数,或者超出图片范围。
// 4.1 处理越界逻辑
let finalX = cropX;
let finalY = cropY;
let finalW = cropW;
let finalH = cropH;
// 如果起始点小于 0
if (finalX < 0) {
finalW += finalX; // 宽度减去越界的部分 (finalX 是负数)
finalX = 0;
}
if (finalY < 0) {
finalH += finalY;
finalY = 0;
}
// -------- 【关键】你原来的逻辑:有 rect_info 就覆盖比例 --------
if (rect_info) {
RATIO = {
left: rect_info.leftDistance / canvasWidth, // ✅ 转成比例
top: rect_info.topDistance / canvasHeight, // ✅ 转成比例
width: rect_info.rectWidth / canvasWidth, // ✅ 比例
height: rect_info.rectHeight / canvasHeight, // ✅ 比例
};
}
// 如果结束点超出图片范围
if (finalX + finalW > realW) {
finalW = realW - finalX;
}
if (finalY + finalH > realH) {
finalH = realH - finalY;
}
console.log("✅ 正确比例:", RATIO);
// 4.2 最终检查:如果宽高小于等于0,说明打印区域完全没有覆盖图片,或者图片极小
if (finalW <= 0 || finalH <= 0) {
console.warn(
"警告:计算出的裁剪区域无效,可能图片未覆盖打印区域。输出原图。",
);
// 这种情况可以根据业务决定是报错还是返回原图,这里演示返回原图
await sharp(inputPath).toFile(outputPath);
} else {
// 5. 执行裁剪
await sharp(inputPath)
.extract({
left: finalX,
top: finalY,
width: finalW,
height: finalH,
})
.toFile(outputPath);
}
try {
// 1. 获取图片宽高
const meta = await sharp(inputPath).metadata();
const width = meta.width;
const height = meta.height;
// 2. 按比例计算(你原来的写法,完全不变)
const cropLeft = Math.round(width * RATIO.left);
const cropTop = Math.round(height * RATIO.top);
const cropWidth = Math.round(width * RATIO.width);
const cropHeight = Math.round(height * RATIO.height);
// 安全边界
const safeLeft = Math.max(0, cropLeft);
const safeTop = Math.max(0, cropTop);
const safeWidth = Math.min(cropWidth, width - safeLeft);
const safeHeight = Math.min(cropHeight, height - safeTop);
// 3. 执行裁剪(你原来的逻辑不变)
await sharp(inputPath)
.extract({
left: safeLeft,
top: safeTop,
width: safeWidth,
height: safeHeight,
})
.toFile(outputPath);
// 6. 返回结果结构 (保持你原来的格式)
// 4. 返回你要的结构(完全不变)
const results = [
{
file: path.basename(inputPath),
status: "cropped",
outputPath: outputPath,
originalSize: { width: realW, height: realH },
newSize: { width: finalW, height: finalH },
originalSize: { width, height },
newSize: { width: safeWidth, height: safeHeight },
cropArea: {
x: finalX,
y: finalY,
width: finalW,
height: finalH,
x: safeLeft,
y: safeTop,
width: safeWidth,
height: safeHeight,
},
},
];
// 删除临时文件
if (fs.existsSync(inputPath)) {
fs.unlinkSync(inputPath);
}
fs.unlinkSync(inputPath);
return results;
} catch (error) {
console.error("裁剪过程出错:", error);
throw new Error("图片裁剪失败: " + error.message);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment