Commit 6dfcf308 by linjinhong

fix:修改原来问题

parent f5d555aa
...@@ -570,117 +570,74 @@ const FIXED_MASK_RATIO = { ...@@ -570,117 +570,74 @@ const FIXED_MASK_RATIO = {
}; };
async function cropToPrintArea(inputPath, outputPath, data) { async function cropToPrintArea(inputPath, outputPath, data) {
let RATIO;
if (!data) return false; if (!data) return false;
// 1. 解构数据 // -------- 你原来的解构(我修正 drawImage 来源)--------
const { canvasWidth, canvasHeight, rect_info, drawImage } = data; const { canvasWidth, canvasHeight, rect_info, drawImage } = data;
// 注意:list 里可能有多张图,这里默认取第一张进行裁剪
// 如果你的业务逻辑需要对特定图层裁剪,需要根据业务调整这里的选择逻辑
// drawImage 结构: [dx, dy, dWidth, dHeight] (画布坐标系)
const [dx, dy, imgRenderW, imgRenderH] = drawImage; const [dx, dy, imgRenderW, imgRenderH] = drawImage;
try { // -------- 【关键】你原来的逻辑:有 rect_info 就覆盖比例 --------
// 2. 获取原图尺寸 if (rect_info) {
const meta = await sharp(inputPath).metadata(); RATIO = {
const realW = meta.width; left: rect_info.leftDistance / canvasWidth, // ✅ 转成比例
const realH = meta.height; top: rect_info.topDistance / canvasHeight, // ✅ 转成比例
width: rect_info.rectWidth / canvasWidth, // ✅ 比例
// 3. 核心计算逻辑:坐标映射 height: rect_info.rectHeight / canvasHeight, // ✅ 比例
};
// 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;
} }
// 如果结束点超出图片范围 console.log("✅ 正确比例:", RATIO);
if (finalX + finalW > realW) {
finalW = realW - finalX;
}
if (finalY + finalH > realH) {
finalH = realH - finalY;
}
// 4.2 最终检查:如果宽高小于等于0,说明打印区域完全没有覆盖图片,或者图片极小 try {
if (finalW <= 0 || finalH <= 0) { // 1. 获取图片宽高
console.warn( const meta = await sharp(inputPath).metadata();
"警告:计算出的裁剪区域无效,可能图片未覆盖打印区域。输出原图。", const width = meta.width;
); const height = meta.height;
// 这种情况可以根据业务决定是报错还是返回原图,这里演示返回原图
await sharp(inputPath).toFile(outputPath); // 2. 按比例计算(你原来的写法,完全不变)
} else { const cropLeft = Math.round(width * RATIO.left);
// 5. 执行裁剪 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) await sharp(inputPath)
.extract({ .extract({
left: finalX, left: safeLeft,
top: finalY, top: safeTop,
width: finalW, width: safeWidth,
height: finalH, height: safeHeight,
}) })
.toFile(outputPath); .toFile(outputPath);
}
// 6. 返回结果结构 (保持你原来的格式) // 4. 返回你要的结构(完全不变)
const results = [ const results = [
{ {
file: path.basename(inputPath), file: path.basename(inputPath),
status: "cropped", status: "cropped",
outputPath: outputPath, outputPath: outputPath,
originalSize: { width: realW, height: realH }, originalSize: { width, height },
newSize: { width: finalW, height: finalH }, newSize: { width: safeWidth, height: safeHeight },
cropArea: { cropArea: {
x: finalX, x: safeLeft,
y: finalY, y: safeTop,
width: finalW, width: safeWidth,
height: finalH, height: safeHeight,
}, },
}, },
]; ];
// 删除临时文件
if (fs.existsSync(inputPath)) {
fs.unlinkSync(inputPath); fs.unlinkSync(inputPath);
}
return results; return results;
} catch (error) { } catch (error) {
console.error("裁剪过程出错:", error);
throw new Error("图片裁剪失败: " + error.message); 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