1

我一直在使用库“画布”来编辑带有线性渐变的图像(通过 URL),并且我一直在使用一些方法。但我还不能得到正确的结果。

我在画布上使用了这些方法,但任何东西都适用于 React。你知道用线性渐变编辑图像并将其转换为 base64 的另一种方法吗?


第一种方法

    import { loadImage, createCanvas } from 'canvas'

    useEffect(() => {
      const coversheet = 'https://...'
      const canvas = createCanvas('600', '286')
      const ctx = canvas.getContext('2d')

      loadImage(coversheet).then( image => {
        ctx.drawImage(image, 340, 515, 70, 70)
        let gradient = ctx.createLinearGradient(0, 0, 170, 0)
        gradient.addColorStop(0, 'white')
        gradient.addColorStop(1, 'red')
        ctx.fillStyle = gradient
        ctx.fillRect(20, 20, 150, 100)
      })

      let base64 = canvas.toDataURL('image/jpeg')
      setCoversheetSrc(base64)
    }, [])

使用这种方法,我什么也得不到,这会在 base64 中返回一个黑色图像(当它是'image/jpeg' 类型时它是黑色的)。


第二种方法

  import { createCanvas, Image } from 'canvas'

  useEffect(() => { 
    const coversheet = 'https://...'
    const canvas = createCanvas('600', '286')
    const ctx = canvas.getContext('2d')

    const img = new Image()
    img.crossOrigin = 'Anonymous'
    img.onload = () => {
      ctx.drawImage(this, 340, 515, 70, 70)
      let gradient = ctx.createLinearGradient(0, 0, 170, 0)
      gradient.addColorStop(0, 'white')
      gradient.addColorStop(1, 'red')
      ctx.fillStyle = gradient
      ctx.fillRect(20, 20, 150, 100)
    }
    img.src = coversheet

    let base64 = canvas.toDataURL()
    setCoversheetSrc(base64)
  }, [])

使用此代码,我收到此错误消息:

TypeError: canvas__WEBPACK_IMPORTED_MODULE_2__.Image 不是构造函数。

指出这一行“const img = new Image()”


第三种方法:

  import { loadImage, createCanvas } from 'canvas'

  useEffect(() => {
      const runCanvas = async () => {
      const coversheet = 'https://...'

      const canvas = await createCanvas('600', '286')
      const ctx = await canvas.getContext('2d')
      const image = await loadImage(coversheet)

      ctx.drawImage(image, 340, 515, 70, 70)
      let gradient = ctx.createLinearGradient(0, 0, 170, 0)
      gradient.addColorStop(0, 'white')
      gradient.addColorStop(1, 'red')
      ctx.fillStyle = gradient
      ctx.fillRect(20, 20, 150, 100)

      let base64 = await canvas.toDataURL('image/jpeg')
      setCoversheetSrc(base64)
    }
    runCanvas()
  }, [])

有了这个,我收到了这个错误:

未处理的拒绝(SecurityError):无法在“HTMLCanvasElement”上执行“toDataURL”:可能无法导出受污染的画布。

4

1 回答 1

0
  1. import { createCanvas, Image } from 'canvas'适用于此处记录的库的 1.x 版本。您最有可能使用 2.x。

  2. “受污染的画布不得出口。” 表示您已将跨域图像加载到画布中。因此,出于安全原因,您不能像记录toDataURL的那样调用它。

您必须在该图像响应上添加适当的 CORS 标头,或者,如果服务器不在您的控制之下,您也可以通过您自己的代理它并使用适当的 CORS 标头提供服务。这些都在此处正确记录。

于 2021-01-05T09:14:55.853 回答