You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Canvas drawImage裁剪图片出现模糊问题的求助

Chrome扩展十字光标截图工具Canvas裁剪模糊问题

我正在开发Chrome扩展的十字光标截图工具,使用chrome.tabs.captureVisibleTab API获取页面可见区域的截图后,用HTML5 Canvas的drawImage方法裁剪用户选中的区域,但输出的图片出现模糊问题:

模糊的裁剪效果

初始裁剪函数

function cropImage(
  src: string,
  cropArea: { left: number; top: number; width: number; height: number }
): Promise<HTMLCanvasElement> {
  return new Promise((resolve, reject) => {
    const { left, top, width, height } = cropArea;

    const img = document.createElement('img');
    img.src = src;
    img.onload = function () {
      // TODO: remove this: just for testing
      document.body.appendChild(img);

      try {
        const canvas = document.createElement('canvas');

        canvas.width = width;
        canvas.height = height;

        const ctx = canvas.getContext('2d');

        const devicePixelRatio = window.devicePixelRatio || 1;

        ctx.drawImage(
          img,
          left * devicePixelRatio,
          top * devicePixelRatio,
          width * devicePixelRatio,
          height * devicePixelRatio,
          0,
          0,
          width,
          height
        );

        resolve(canvas);
      } catch (error) {
        reject(error);
      }
    };
    img.onerror = function (event, source, lineno, colno, error) {
      reject(error);
    };
  });
}

初始渲染代码

const canvas = await cropImage(response.imgSrc, {
  left: left - window.scrollX,
  top: top - window.scrollY,
  width,
  height,
});

const croppedImg = new Image();
const croppedSrc = canvas.toDataURL('image/jpeg', 1.0);
croppedImg.src = croppedSrc;
document.body.appendChild(croppedImg);

我尝试过设置ctx.imageSmoothingEnabled = false,但没有效果。设备为Macbook Pro,window.devicePixelRatio = 2。


更新:临时解决方案

按照建议,我修改了Canvas的尺寸,让它保留高分辨率,不再通过drawImage缩小图片,而是让img标签自行缩放,得到了清晰的效果,但这只是临时方案——我需要对裁剪后的图片进行后续操作,希望Canvas能原生处理这个问题。

更新后的裁剪函数

export function cropImage(
  src: string,
  cropArea: { left: number; top: number; width: number; height: number }
): Promise<HTMLCanvasElement> {
  return new Promise((resolve, reject) => {
    const { left, top, width, height } = cropArea;

    const img = document.createElement('img');
    img.src = src;
    img.onload = function () {
      // TODO: remove this: just for testing
      document.body.appendChild(img);

      try {
        const canvas = document.createElement('canvas');
        const devicePixelRatio = window.devicePixelRatio || 1;

        canvas.width = width * devicePixelRatio;
        canvas.height = height * devicePixelRatio;

        const ctx = canvas.getContext('2d');

        ctx.drawImage(
          img,
          left * devicePixelRatio,
          top * devicePixelRatio,
          width * devicePixelRatio,
          height * devicePixelRatio,
          0,
          0,
          width * devicePixelRatio,
          height * devicePixelRatio
        );

        resolve(canvas);
      } catch (error) {
        reject(error);
      }
    };
    img.onerror = function (event, source, lineno, colno, error) {
      reject(error);
    };
  });
}

更新后的渲染代码

const canvas = await cropImage(
  response.imgSrc,
  {
    left: left - window.scrollX,
    top: top - window.scrollY,
    width,
    height,
  }
);

const croppedImg = new Image();
croppedImg.src = canvas.toDataURL('image/jpeg', 1.0);
document.body.appendChild(croppedImg);

修复后的效果:

清晰的裁剪效果

内容的提问来源于stack exchange,提问作者Vishal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:33:27