簡體   English   中英

如何使用 drawImage 將圖像旋轉變換復制到 canvas

[英]How to copy image rotation transform on to canvas with drawImage

我在網上看到過這個問題,例如:

HTML5 canvas 以一定角度繪制圖像

http://creativejs.com/2012/01/day-10-drawing-rotated-images-into-canvas/

但到目前為止,我沒有成功地將它們應用於我的問題。

const TO_RADIANS = Math.PI / 180

export function cropPreview(
  image: HTMLImageElement,
  canvas: HTMLCanvasElement,
  crop: PixelCrop,
  scale = 1,
  rotate = 0,
) {
  const ctx = canvas.getContext('2d')

  if (!ctx) {
    throw new Error('No 2d context')
  }

  const scaleX = image.naturalWidth / image.width
  const scaleY = image.naturalHeight / image.height
  const pixelRatio = window.devicePixelRatio || 1

  canvas.width = Math.floor(crop.width * pixelRatio * scaleX)
  canvas.height = Math.floor(crop.height * pixelRatio * scaleY)

  ctx.scale(pixelRatio, pixelRatio)
  ctx.imageSmoothingQuality = 'high'

  const cropX = crop.x * scaleX
  const cropY = crop.y * scaleY
  const cropWidth = crop.width * scaleX
  const cropHeight = crop.height * scaleY

  const rotateRads = rotate * TO_RADIANS
  const centerX = image.width / 2
  const centerY = image.height / 2

  ctx.save()
  ctx.translate(centerX, centerY)
  ctx.rotate(rotateRads)

  ctx.drawImage(image, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight)

  ctx.restore()
}

這是一個有問題的現場游樂場,只需選擇一個圖像並應用一些旋轉: CodeSandbox image rotation

我在這里做錯了什么? 即使應用了旋轉,底部圖像也應准確顯示裁剪區域中的內容。

錯誤轉換的作物預覽

這是您更新后的 function


export async function cropPreview(
  image: HTMLImageElement,
  canvas: HTMLCanvasElement,
  crop: PixelCrop,
  scale = 1,
  rotate = 0,
) {
  const ctx = canvas.getContext('2d')

  if (!ctx) {
    throw new Error('No 2d context')
  }

  const scaleX = image.naturalWidth / image.width
  const scaleY = image.naturalHeight / image.height
  const pixelRatio = window.devicePixelRatio || 1

  canvas.width = Math.floor(crop.width * pixelRatio * scaleX)
  canvas.height = Math.floor(crop.height * pixelRatio * scaleY)

  ctx.scale(pixelRatio, pixelRatio)
  ctx.imageSmoothingQuality = 'high'

  const cropX = crop.x * scaleX
  const cropY = crop.y * scaleY
  const cropWidth = crop.width * scaleX
  const cropHeight = crop.height * scaleY

  const rotateRads = rotate * TO_RADIANS
  const centerX = image.width / 2
  const centerY = image.height / 2

  ctx.save()

  // 5) Move the crop origin to the canvas origin (0,0)
  ctx.translate(-cropX, -cropY) 
  // 4) Move the origin to the center of the original position
  ctx.translate(centerX, centerY) 
  // 3) Rotate around the origin
  ctx.rotate(rotateRads) 
  // 2) Scaled the image
  ctx.scale(scale, scale) 
  // 1) Move the center of the image to the origin (0,0)
  ctx.translate(-centerX, -centerY) 
  ctx.drawImage(
    image,
    0,
    0,
    image.width,
    image.height,
    0,
    0,
    image.width,
    image.height,
  )

  ctx.restore()
}

與其試圖弄清楚如何裁剪,不如讓 canvas 裁剪它。

轉換的應用順序與它們出現的順序相反,所以我正在做的是

  1. 將圖像的中心移動到原點 (0,0)
  2. 縮放圖像
  3. 繞原點旋轉
  4. 將原點移動到原來的中心 position
  5. 將crop原點移動到canvas原點(0,0)

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM