获取图片裁剪到边缘的坐标

支持获取图片旋转,水平翻转,垂直翻转后的边缘坐标

export function clearImageEdgeBlank(image: HTMLCanvasElement, {
  padding = 0, rotate = 0, flipV = false, flipH = false,
}): Promise<{
    contentWidth: number;
    contentHeight: number;
    top: number;
    left: number;
    frameSize: number;
  }> {
  return new Promise((resolve, reject) => {
    // create canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    let scale = 1;
    const maxLength = Math.max(image.width, image.height);
    if (maxLength > 1000) {
      scale = maxLength / 1000;
    }
    const imageWidth = image.width / scale;
    const imageHeight = image.height / scale;
    const frameSize = translateXYToLine({ x: 0, y: 0 }, { x: imageWidth, y: imageHeight });
    canvas.width = frameSize;
    canvas.height = frameSize;
    const x = canvas.width / 2;
    const y = canvas.height / 2;

    const canvasImage = document.createElement('canvas');
    const ctxImage = canvasImage.getContext('2d');
    canvasImage.width = imageWidth;
    canvasImage.height = imageHeight;
    if (flipV || flipH) {
      ctxImage?.translate(flipH ? imageWidth : 0, flipV ? imageHeight : 0);
      ctxImage?.scale(flipH ? -1 : 1, flipV ? -1 : 1);
    }
    ctxImage?.drawImage(image, 0, 0, imageWidth, imageHeight);
    ctx?.translate(x, y);
    if (rotate) {
      ctx?.rotate(rotate * Math.PI / 180);
    }
    ctx?.translate(-x, -y);
    ctx?.drawImage(canvasImage, x - imageWidth / 2, y - imageHeight / 2);
    const imageData = ctx?.getImageData(0, 0, canvas.width, canvas.height);
    const { data = [], width = 0, height = 0 } = imageData || {};

    // 左偏移,从左开始一列一列的查找
    const getOffsetLeft = () => {
      for (let i = 0; i < width; i += 1) {
        for (let j = 0; j < height; j += 1) {
          const pxStartIndex = (j * width + i) * 4;
          if (data[pxStartIndex + 3] > 0) {
            return Promise.resolve(i);
          }
        }
      }
      return Promise.resolve(0);
    };

    // 上偏移,从左开始,一行一行的查找
    const getOffsetTop = () => {
      for (let i = 0; i < height; i += 1) {
        for (let j = 0; j < width; j += 1) {
          const pxStartIndex = (i * width + j) * 4;
          if (data[pxStartIndex + 3] > 0) {
            return Promise.resolve(i);
          }
        }
      }
      return Promise.resolve(0);
    };

    // 右偏移,从右开始,一列一列的查找
    const getOffsetRight = () => {
      for (let i = width - 1; i >= 0; i -= 1) {
        for (let j = 0; j < height; j += 1) {
          const pxStartIndex = (j * width + i) * 4;
          if (data[pxStartIndex + 3] > 0) {
            return Promise.resolve(i);
          }
        }
      }
      return Promise.resolve(0);
    };

    // 下偏移,从右开始,一行一行的查找
    const getOffsetBottom = () => {
      for (let i = height - 1; i >= 0; i -= 1) {
        for (let j = 0; j < width; j += 1) {
          const pxStartIndex = (i * width + j) * 4;
          if (data[pxStartIndex + 3] > 0) {
            return Promise.resolve(i);
          }
        }
      }
      return Promise.resolve(0);
    };

    const queue = [
      getOffsetLeft(),
      getOffsetTop(),
      getOffsetRight(),
      getOffsetBottom(),
    ];
    Promise.all(queue).then((res) => {
      let [startX, startY, endX, endY] = res;
      // 加上padding
      startX -= padding;
      startY -= padding;
      endX += padding;
      endY += padding;
      const contentWidth = endX - startX;
      const contentHeight = endY - startY;
      const top = startY;
      const left = startX;
      // rosolve裁剪后的图像字符串
      resolve({
        contentWidth: contentWidth * scale,
        contentHeight: contentHeight * scale,
        top: top * scale,
        left: left * scale,
        frameSize: frameSize * scale,
      });
    });
  });
}

  

posted @ 2023-08-30 15:27  瑞瑞大人  阅读(23)  评论(0编辑  收藏  举报