Files
TrueGrowth/docs/TRANSPARENT_BORDER_TRIM.md

3.9 KiB
Raw Blame History

透明边框裁剪优化

问题描述

对于基于透明度切分的场景(如合并图片还原),需要实现严格的"去透明边"逻辑:

  • 去除图片四周完全透明的区域alpha = 0
  • 保留任何包含非透明像素的区域alpha > 0

修改内容

1. trimTransparentBorders 函数增强

位置: packages/drawnix/src/utils/image-splitter.ts:1044

修改前:

  • 使用 isTransparentPixel 函数,默认阈值为 50
  • alpha < 50 的像素被认为是透明的
  • 可能会误裁剪半透明的内容

修改后:

function trimTransparentBorders(
  imageData: ImageData,
  strict: boolean = true
): { top: number; right: number; bottom: number; left: number }
  • 新增 strict 参数(默认 true
  • 严格模式 (strict = true): 只有 alpha = 0 才认为是透明,避免裁剪任何非完全透明的像素
  • 非严格模式 (strict = false): alpha < 50 认为是透明,保持原有行为

2. splitImageByLines 函数应用严格裁剪

位置: packages/drawnix/src/utils/image-splitter.ts:897

修改前:

if (hasAlpha) {
  // 合并图片:不裁剪边框,保持完整
  borders = { top: 0, right: sw - 1, bottom: sh - 1, left: 0 };
}

修改后:

if (hasAlpha) {
  // 透明图片:使用严格模式裁剪透明边框
  // 只去除完全透明alpha=0的边缘保留任何包含非透明像素的区域
  borders = trimTransparentBorders(regionData, true);
}

技术细节

严格透明检测算法

const alphaThreshold = strict ? 0 : 50;

const isRowTransparent = (y: number): boolean => {
  for (let x = 0; x < width; x++) {
    const idx = (y * width + x) * 4;
    const alpha = data[idx + 3];
    if (alpha > alphaThreshold) {
      return false; // 发现非透明像素,该行不是完全透明
    }
  }
  return true; // 整行都是透明的
};

裁剪逻辑

  1. 从四个方向扫描:顶部、底部、左侧、右侧
  2. 逐行/逐列检查:检查每一行/列是否所有像素都满足透明条件
  3. 停止条件:遇到第一个包含非透明像素的行/列时停止
  4. 返回边界:返回内容区域的边界坐标

使用场景

适用场景

  • 合并图片还原(透明分割线)
  • AI 生成的透明背景图片
  • 需要精确保留边缘内容的场景

不适用场景

  • 普通白色背景图片(使用 trimWhiteBordersOnly
  • 需要去除半透明边缘的场景(使用非严格模式)

测试建议

测试用例

  1. 完全透明边缘

    • 输入:四周有 10px 完全透明alpha=0的边缘
    • 期望:边缘被完全裁剪
  2. 半透明边缘

    • 输入:四周有 10px 半透明alpha=128的边缘
    • 期望:边缘被保留(不裁剪)
  3. 混合边缘

    • 输入:顶部完全透明,其他边有半透明内容
    • 期望:只裁剪顶部,其他边保留
  4. 无透明边缘

    • 输入:边缘直接是不透明内容
    • 期望:不裁剪任何内容

验证方法

// 在浏览器控制台查看日志
// 日志会显示裁剪前后的尺寸和边界信息
console.log('[splitImageByLines] Transparent image: strict transparent border trim', {
  row, col,
  originalSize: { width: sw, height: sh },
  borders,
  trimmedSize: {
    width: borders.right - borders.left + 1,
    height: borders.bottom - borders.top + 1
  }
});

性能考虑

  • 时间复杂度: O(width × height),需要扫描所有边缘像素
  • 优化建议:
    • 对于大图片,可以考虑采样检测
    • 可以提前终止扫描(遇到非透明像素立即停止)

相关文件

  • packages/drawnix/src/utils/image-splitter.ts - 主要实现
  • packages/drawnix/src/utils/image-border-utils.ts - 边框检测工具

版本历史

  • 2026-01-09: 初始实现,支持严格透明边框裁剪