1***@qq.com
1***@qq.com
  • 发布:2023-03-12 23:57
  • 更新:2023-03-13 11:11
  • 阅读:342

在App端,调用canvasToTempFilePath方法报错,而且图片没有跨域引用的是本地图片。

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: 11

HBuilderX类型: 正式

HBuilderX版本号: 3.7.6

手机系统: Android

手机系统版本号: Android 10

手机厂商: 小米

手机机型: Redmi Note 9

页面类型: vue

vue版本: vue3

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
// 这是在renderjs中使用的  
export const draw = async (instance: any, referenceId = '#reference', outputId = '#output') => {  
  // 等待字体加载完成  
  await document.fonts.load('12px share-title')  
  await document.fonts.load('12px share-sub-title')  
  await document.fonts.load('12px iconfont')  

  // 获取对比容器  
  const reference = document.querySelector(referenceId)  
  // 开始绘制  
  // @ts-ignore  
  html2canvas(reference, { allowTaint: true, useCORS: true, logging: true }).then((canvas: HTMLCanvasElement) => {  
    const output = document.querySelector(outputId) as HTMLDivElement  
    const outputCanvas = output.querySelector('canvas') as HTMLCanvasElement  

    const ctx = outputCanvas.getContext('2d', { willReadFrequently: true })!  
    const pixelRatio = window.devicePixelRatio  
    const width = canvas.width / pixelRatio  
    const height = canvas.height / pixelRatio  

    // 设置画布宽高  
    output.style.width = width / pixelRatio + 'px'  
    output.style.height = height / pixelRatio + 'px'  
    outputCanvas.height = height  
    outputCanvas.width = width  

    ctx.clearRect(0, 0, width, height)  

    // 将绘制完成的 canvas 放入 uniapp 组件的 canvas  
    ctx.drawImage(canvas, 0, 0, Math.ceil(width / pixelRatio), Math.ceil(height / pixelRatio))  

    instance.$ownerInstance.callMethod('changeLoading')  
  })  
}

操作步骤:

1.DOM 模板

<div>  
    <div  
           id="reference"  
           class="absolute top-0 left-0 w-full bg-cover bg-no-repeat h-[100vh]"  
         >  
          <image src="/static/images/default.png" alt="" />  
    </div>  

    <canvas id="output" canvas-id="output-canvas"></canvas>  
</div>

2.使用 renderjs 模块

<script module="render" lang="renderjs">  
import { draw } from '@/utils/share'  

export default {  
  methods: {  
    async updateData(modelValue) {  
      if (modelValue) { draw(this) }  
    }  
  },  
}  
</script>

3.基于渲染的 dom 元素 渲染成为 canvas

// 这是在renderjs中使用的  
export const draw = async (instance: any, referenceId = '#reference', outputId = '#output') => {  
  // 等待字体加载完成  
  await document.fonts.load('12px share-title')  
  await document.fonts.load('12px share-sub-title')  
  await document.fonts.load('12px iconfont')  

  // 获取对比容器  
  const reference = document.querySelector(referenceId)  
  // 开始绘制  
  // @ts-ignore  
  html2canvas(reference, { allowTaint: true, useCORS: true, logging: true }).then((canvas: HTMLCanvasElement) => {  
    const output = document.querySelector(outputId) as HTMLDivElement  
    const outputCanvas = output.querySelector('canvas') as HTMLCanvasElement  

    const ctx = outputCanvas.getContext('2d', { willReadFrequently: true })!  
    const pixelRatio = window.devicePixelRatio  
    const width = canvas.width / pixelRatio  
    const height = canvas.height / pixelRatio  

    // 设置画布宽高  
    output.style.width = width / pixelRatio + 'px'  
    output.style.height = height / pixelRatio + 'px'  
    outputCanvas.height = height  
    outputCanvas.width = width  

    ctx.clearRect(0, 0, width, height)  

    // 将绘制完成的 canvas 放入 uniapp 组件的 canvas  
    ctx.drawImage(canvas, 0, 0, Math.ceil(width / pixelRatio), Math.ceil(height / pixelRatio))  

    instance.$ownerInstance.callMethod('changeLoading')  
  })  
}

预期结果:

预期结果是可以下载canvas的文件

实际结果:
23:31:24.457 [TIP] :#1 0ms Starting document clone with size 394x804 scrolled to 0,0 at https://img.coregem.net/js/html2canvas.min.js:22  
23:31:25.181 [TIP] :#1 722ms Document cloned, element located at -394.18182373046875,0 with size 394.18182373046875x700 using computed rendering at https://img.coregem.net/js/html2canvas.min.js:22  
23:31:25.190 [TIP] :#1 722ms Starting DOM parsing at https://img.coregem.net/js/html2canvas.min.js:22  
23:31:25.245 [TIP] :#1 782ms Added image file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/static/images/default.png at https://img.coregem.net/js/html2canvas.min.js:22  
23:31:25.261 [TIP] :#1 799ms Starting renderer for element at -394.18182373046875,0 with size 395x700 at https://img.coregem.net/js/html2canvas.min.js:22  
23:31:25.263 [TIP] :#1 800ms Canvas renderer initialized (395x700) with scale 2.75 at https://img.coregem.net/js/html2canvas.min.js:22  
23:31:25.308 [TIP] :#1 850ms Finished rendering at https://img.coregem.net/js/html2canvas.min.js:22  
23:31:25.324 Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.  
Error: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.  
    at o (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:155807)  
    at Ea (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29262)  
    at Ca (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29339)  
    at qa (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:31263)  
    at file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:151322  
    at Ea (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29262)  
    at Ca (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29339)  
    at _ (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:34185)  
    at Ea (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29270)  
    at Ua (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:30772) at uni-app-view.umd.js:1

bug描述:

  • 使用 renderjs + html2canvas 在App端引入本地图片渲染报错

Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
Error: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
at o (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:155807)
at Ea (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29262)
at Ca (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29339)
at qa (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:31263)
at file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:151322
at Ea (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29262)
at Ca (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29339)
at _ (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:34185)
at Ea (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:29270)
at Ua (file:///storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/www/uni-app-view.umd.js:1:30772) at uni-app-view.umd.js:1

2023-03-12 23:57 负责人:无 分享
已邀请:
1***@qq.com

1***@qq.com (作者)

在 红米K20pro 上可以正常使用canvasToTempFilePath函数,只有某些手机中报这个错误

  // 这个是保存的逻辑  
  const saveImage = () => {  
    uni.showLoading({ title: '保存中' })  
    typeof canvasId === 'function' ? (canvasId = canvasId()) : null  
    uni.canvasToTempFilePath(  
      {  
        canvasId,  
        success({ tempFilePath }) {  
          // #ifdef H5  
          downloadImage(tempFilePath)  
          // #endif  
          // #ifdef APP-PLUS  
          saveImageToApp(tempFilePath)  
          // #endif  
        },  
        fail(r) {  
          uni.hideLoading()  
          console.log(r)  

          uni.showToast({ title: '保存失败', icon: 'none' })  
        },  
      },  
      instance,  
    )  
  }
DCloud_UNI_GSQ

DCloud_UNI_GSQ

https://github.com/dcloudio/uni-app/issues/4196

该问题目前已经被锁定, 无法添加新回复