图像缩放

Canvas图像缩放详解,掌握等比缩放、自适应缩放、高质量缩放等实用技巧。使用drawImage的缩放参数可以调整图像大小,实现放大或缩小效果。

缩放语法

ctx.drawImage(image, x, y, width, height)
参数说明
x, y目标位置
width目标宽度
height目标高度

基本缩放

const img = new Image()
img.onload = function() {
  // 缩小到一半
  ctx.drawImage(img, 0, 0, img.width / 2, img.height / 2)
  
  // 放大两倍
  ctx.drawImage(img, 200, 0, img.width * 2, img.height * 2)
}
img.src = 'image.png'

缩放演示

图像缩放效果

等比缩放

保持图像宽高比进行缩放:

function scaleImage(img, maxWidth, maxHeight) {
  const ratio = Math.min(maxWidth / img.width, maxHeight / img.height)
  return {
    width: img.width * ratio,
    height: img.height * ratio
  }
}

const size = scaleImage(img, 300, 200)
ctx.drawImage(img, 0, 0, size.width, size.height)

等比缩放演示

等比缩放(保持宽高比)

填充缩放

拉伸图像填满指定区域(可能变形):

function stretchImage(img, x, y, width, height) {
  ctx.drawImage(img, x, y, width, height)
}

填充缩放演示

拉伸填充(可能变形)

居中缩放

将缩放后的图像居中显示:

function drawImageCentered(img, x, y, maxWidth, maxHeight) {
  const ratio = Math.min(maxWidth / img.width, maxHeight / img.height)
  const w = img.width * ratio
  const h = img.height * ratio
  
  ctx.drawImage(img, x - w / 2, y - h / 2, w, h)
}

居中缩放演示

居中缩放显示

图像平滑质量

控制缩放时的图像质量:

// 高质量平滑
ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = 'high'

// 中等质量
ctx.imageSmoothingQuality = 'medium'

// 低质量(快速)
ctx.imageSmoothingQuality = 'low'

// 禁用平滑(像素化效果)
ctx.imageSmoothingEnabled = false

平滑质量对比

缩放质量对比

缩放工具函数

function fitImage(img, containerWidth, containerHeight, mode) {
  const imgRatio = img.width / img.height
  const containerRatio = containerWidth / containerHeight
  
  let drawWidth, drawHeight, drawX, drawY
  
  if (mode === 'cover') {
    if (imgRatio > containerRatio) {
      drawHeight = containerHeight
      drawWidth = drawHeight * imgRatio
      drawX = (containerWidth - drawWidth) / 2
      drawY = 0
    } else {
      drawWidth = containerWidth
      drawHeight = drawWidth / imgRatio
      drawX = 0
      drawY = (containerHeight - drawHeight) / 2
    }
  } else {
    if (imgRatio > containerRatio) {
      drawWidth = containerWidth
      drawHeight = drawWidth / imgRatio
      drawX = 0
      drawY = (containerHeight - drawHeight) / 2
    } else {
      drawHeight = containerHeight
      drawWidth = drawHeight * imgRatio
      drawX = (containerWidth - drawWidth) / 2
      drawY = 0
    }
  }
  
  return { x: drawX, y: drawY, width: drawWidth, height: drawHeight }
}

注意事项

缩放质量

放大图像会导致模糊,建议使用高分辨率源图像。

性能影响

频繁缩放大图像会影响性能,考虑预缩放缓存。

宽高比

注意保持宽高比避免图像变形。