• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    关于canvas.toDataURL 在iOS运行失败的问题解决

    最近做了一个海报生成的组件,需要drawimage到画布上,image来源包括本地和异地的图片src;
    首先讲一点,异地图片如果不设置允许跨域访问,canvas.toDataURL是无法画image的,报画布污染的错;首先放一张我要生成的图;

    上面加载了两张本地图片,两张异地图片,写了一些文字;在windows谷歌浏览器跑是好的,是吧,图片画出来,感觉无压力;用安卓也是好的,很开心;可是到IOS手机上,我去,怎么图片显示不出来啊,然后
    try catch 错误,没啥有用的信息;

    try {
     // 将canvas对象转化为image/png
       var dataUrl = canvas.toDataURL('image/png')
     } catch (err) {
       console.log(err)
     }
    
    

    我擦,这怎么办???
    然后去cnbing搜,好多相同问题,好多原因,有个老外说动态更改canvas宽高无法再ios画出图片;还有的人说:
    图片文件 size 太大,是否图片超过了 3M ? -----------我看了下生成的图片才几百kb PASS

    图片的 dimension 太大,是否图片尺寸超过了 1000 x 1000 像素?我的尺寸确实超过了,宽高都超了,然而测试了下小的宽高,照旧ios画不出来啊~~~PASS

    你指定的 mime_type 不支持,你用的是哪个 mime type?—canvas的 toDataURL API我看过了,可以支持三个类型,各试了一遍,无果 PASS
    先上我的代码:

    <template>
        <div id="Poster">
            <div class="mask" @click="hidePoster()"></div>
            <canvas ref="canvas" width="588" height="1044" style="display:none;"></canvas>
            <div ref="box" id="Poster-box" @click.stop>
              <span class="close"  @click="hidePoster()"></span>
            </div>
            <p class="tip">长安按海报发送给朋友</p>
        </div>
    </template>
    
    <script>
    export default {
      data () { // 参数
        const u = navigator.userAgent // ios终端
        const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) // ios终端
        return { // 返回参数
          localUrl: isIOS ? location.href.split('#')[0] : location.href, // 当前路径
          canvas: Object // canvas对象
        }
      },
      mounted () {
        this.initCanvas()
      },
      methods: {
        /**
         * 隐藏海报
         */
        hidePoster () {
          this.$emit('hide')
        },
        /**
         * 加载图片
         * @param {Object} img 图片地址
         * @return {Promise} img dom
         */
        loadImage (img) {
          return new Promise((resolve, reject) => {
            // image dom 对象
            const $image = document.createElement('img')
            if (img.isCross_domain) {
              console.log(img.url)
              $image.setAttribute('crossOrigin', 'Anonymous')
            }
            $image.onload = () => {
              resolve($image)
            }
             $image.src = img.url
            $image.onerror = reject
          })
        },
        /**
         * init初始化canvas函数
         */
        async initCanvas () {
          // 获取vue实例
          var vm = this
          vm.$indicator.open({
            text: '加载中...',
            spinnerType: 'fading-circle'
          })
          this.canvas = this.$refs.canvas.getContext('2d')
          this.canvas.height = 400
          this.canvas.width = 300
          this.canvas.fillStyle = '#ffffff'
          this.canvas.fillRect(0, 0, 588, 1044)
    
          // image urls
          const imgArr = [
            {
              url: require('../assets/poster-banner.png'),
              isCross_domain: false
            },
            {
              url: require('../assets/shadow.png'),
              isCross_domain: false
            },
            {
              url: 'https://s3-011-shinho-syj-uat-bjs.s3.cn-north-1.amazonaws.com.cn/mall/2019_06/border04.png',
              isCross_domain: true
            },
            {
              url: 'https://s3-011-shinho-syj-uat-bjs.s3.cn-north-1.amazonaws.com.cn/mall/2019_06/132.jpg',
              isCross_domain: true
            }
          ]
          // image doms
          await Promise.all(imgArr.map(img => this.loadImage(img))).then((imgs) => {
            console.log('done')
            this.canvas.drawImage(imgs[0], 0, 0, 588, 216 * 2)
            this.canvas.drawImage(imgs[1], 97 * 2, 166 * 2, 100 * 2, 100 * 2)
    
            this.canvas.save()
            this.canvas.beginPath()
            this.canvas.arc(147 * 2, 214 * 2, 34 * 2, 0, 2 * Math.PI, false)
            this.canvas.clip()
            this.canvas.drawImage(imgs[2], 113 * 2, 180 * 2, 68 * 2, 68 * 2)
            this.canvas.restore()
            this.canvas.drawImage(imgs[3], 189 * 2, 409 * 2, 88 * 2, 88 * 2)
            // 绘制文字
            this.drawText('我就是个我就账号账号', 147 * 2, 278 * 2, 290 * 2, '#333333', '32px PingFangSC-Regular ')
            this.drawText('荣誉称号是我', 147 * 2, 300 * 2, 290 * 2, '#999999', '26px PingFangSC-Regular ')
            this.drawText('距离冲榜还差10人', 147 * 2, 340 * 2, 290 * 2, '#FA6F5B', 'bold 36px arial')
            this.drawText('快来助我冲榜赢红烧酱油吧', 147 * 2, 370 * 2, 290 * 2, '#FA6F5B', 'bold 36px arial ')
            this.drawText('扫描二维码', 180 * 2, 443 * 2, 172 * 2, '#333333', '28px PingFangSC-Regular ', 'right')
            this.drawText('直达冲榜活动', 180 * 2, 463 * 2, 172 * 2, '#333333', '28px PingFangSC-Regular ', 'right')
            this.drawText('邀请好友跟你一起冲大奖', 180 * 2, 483 * 2, 172 * 2, '#333333', '28px PingFangSC-Regular ', 'right')
            this.showPic()
            vm.$indicator.close()
          })
        },
        /**
         * 绘制文字
         * @param {String} title  文字名称
         * @param {Number} x  x轴坐标
         * @param {Number} y  y轴坐标
         * @param {Number} maxwidth  最大宽度
         * @param {String} color  颜色
         * @param {String} font  字体样式
         * @param {String} textalign  文字排版
         */
        drawText (title, x, y, maxwidth, color, font, textalign = 'center') {
          this.canvas.font = font
          this.canvas.textAlign = textalign
          this.canvas.fillStyle = color
          this.canvas.fillText(title, x, y, maxwidth)
        },
        /**
         * 显示图片
         */
        showPic () {
          // 获取canvas对象
          let canvas = this.$refs.canvas
    
          try {
            // 将canvas对象转化为image/png
            var dataUrl = canvas.toDataURL('image/png')
          } catch (err) {
            console.log(err)
          }
    
          // 创建img 元素
          var newImg = document.createElement('img')
          newImg.src = dataUrl
          newImg.style.width = '100%'
          newImg.style.height = '100%'
          newImg.className = 'img-poster'
          newImg.style.borderRadius = '8px'
          this.$refs.box.appendChild(newImg)
        }
    
      }
    }
    </script>
    

    盘查了好久,最后找到bug,就是下面这个function

     /**
         * 加载图片
         * @param {Object} img 图片地址
         * @return {Promise} img dom
         */
        loadImage (img) {
          return new Promise((resolve, reject) => {
            // image dom 对象
            const $image = document.createElement('img')
            $image.src = img.url
            if (img.isCross_domain) {
              console.log(img.url)
              $image.setAttribute('crossOrigin', 'Anonymous')
            }
            $image.onload = () => {
              resolve($image)
            }
            $image.onerror = reject
          })
        },
    

    有没有注意到crossOrigin属性是在src属性之后赋值的;/(ㄒoㄒ)/~~
    crossOrigin属性必须在src属性之前赋值
    crossOrigin属性必须在src属性之前赋值
    crossOrigin属性必须在src属性之前赋值
    尽管没有找到准确的文档明确指定crossOrigin属性必须在src属性之前赋值,但是要适配IOS确实要这么做;
    大家如果对 crossorigin 有疑问可以看一下MDN对crossorigin的解释:
    https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_enabled_image

    里面讲了画布的污染和解决方法,就是设置 crossorigin = “Anonymous”;里面的方法也是先设置crossorigin在图片加载完后设置 src;
    如下

    var img = new Image,
        canvas = document.createElement("canvas"),
        ctx = canvas.getContext("2d"),
        src = "http://example.com/image"; // insert image url here
    
    img.crossOrigin = "Anonymous";
    
    img.onload = function() {
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage( img, 0, 0 );
        localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") );
    }
    img.src = src;
    // make sure the load event fires for cached images too
    if ( img.complete || img.complete === undefined ) {
        img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
        img.src = src;
    }
    

    到此这篇关于关于canvas.toDataURL 在iOS运行失败的问题解决 的文章就介绍到这了,更多相关canvas.toDataURL在iOS运行失败内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

    上一篇:canvas绘制图片drawImage使用方法
    下一篇:canvas 绘图时位置偏离的问题解决
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    关于canvas.toDataURL 在iOS运行失败的问题解决 关于,canvas.toDataURL,在,iOS,