如何使用javascript进行图片处理_Canvas API有哪些强大功能?

不能。Canvas API 本身不支持直接读取本地图片文件,必须通过 FileReader 或 URL.createObjectURL() 先加载为 img 元素再绘制;裁剪缩放依赖 drawImage 多参数重载;滤镜需手动像素操作,性能差,推荐 OffscreenCanvas 或 WebAssembly 加速。

Canvas API 能不能直接读取本地图片文件?

不能。Canvas 本身不提供文件读取能力,必须先用 FileReaderURL.createObjectURL() 把图片加载进 元素,再绘制到 上。

常见错误是直接把 File 对象传给 ctx.drawImage(),会报 TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'

  • 推荐用 URL.createObjectURL(file):速度快、不触发 Base64 编码开销
  • 记得在绘制完成后调用 URL.revokeObjectURL(url) 防止内存泄漏
  • 若需兼容老浏览器(如 IE10),才考虑 FileReader.readAsDataURL()

如何用 Canvas 实现基础图片裁剪和缩放?

核心靠 ctx.drawImage() 的多参数重载,不是靠 CSS 或 img 属性。

它有 3 种调用形式,最常用的是 9 参数版本(含目标区域和源区域):

ctx.drawImage(
  image,           // HTMLImageElement
  sx, sy, sw, sh,  // 源矩形:从原图哪块区域取
  dx, dy, dw, dh   // 目标矩形:画到 canvas 哪里、画多大
);
  • 裁剪:设 swsh 小于原图尺寸,只取局部
  • 缩放:设 dwdh 不等于 sw/sh,自动拉伸/压缩
  • 注意:canvas 像素密度受 window.devicePixelRatio 影响,高分屏下要手动缩放 canvas.width/height 才能清晰

Canvas 能否实现高斯模糊或锐化这类滤镜?

原生 Canvas 2D 上下文不支持 CSS-style filter(如 filter: blur(2px)),也没有内置卷积算子。但可以手写像素级操作:

  • ctx.getImageData(x, y, w, h) 获取像素数组(Uint8ClampedArray
  • 对每个 data[i](R)、data[i+1](G)、data[i+2](B)做加权计算
  • 写回后用 ctx.putImageData() 渲染——但注意:这一步极慢,1000×1000 图片可能卡顿 200ms+
  • 生产环境建议用 OffscreenCanvas(Worker 中处理)或 WebAssembly 加速(如 ffmpeg.wasm

简单均值模糊示例(仅示意逻辑,非高性能实现):

const imageData = ctx.getImageData(0, 0, width, height);
const data = imageData.data;
for (let y = 1; y < height - 1; y++) {
  for (let x = 1; x < width - 1; x++) {
    const i = (y * width + x) * 4;
    let r = 0, g = 0, b = 0;
    for (let dy = -1; dy <= 1; dy++) {
      for (let dx = -1; dx <= 1; dx++) {
        const ni = ((y + dy) * width + (x + dx)) * 4;
        r += data[ni]; g += data[ni + 1]; b += data[ni + 2];
      }
    }
    data[i] = r / 9; data[i + 1] = g / 9; data[i + 2] = b / 9;
  }
}
ctx.putImageData(imageData, 0, 0);

toDataURL 和 toBlob 输出的图片质量能控制吗?

可以,但仅限 image/jpegimage/webp 格式;image/png 忽略质量参数。

  • canvas.toDataURL('image/jpeg', 0.8):第二个参数是 0–1 的质量系数
  • canvas.toBlob(callback, 'image/webp', 0.75):同样支持质量参数,且更省内存(不生成长字符串)
  • 注意:Safari 旧版不支持 toBlob 的质量参数,需降级为 toDataURL + dataURLtoBlob 转换
  • WebP 在 iOS 14+ 和 Chrome 85+ 支持良好,但 Android WebView 版本碎片化严重,上线前务必实测

导出前记得检查 canvas 内容是否已渲染完成(比如图片 onload 后再调用),否则输出是空白。