有关canvas.toDataURL 在✤iOS运作不成功的难题处理

日期:2021-03-23 类型:科技新闻 

关键词:如何制作微信小游戏,微信游戏小程序,公众号游戏,h5小游戏模板,小程序游戏源码

近期干了一个宣传海报转化成的部件,必须drawimage到画布上,image来源于包含当地和外地的照片src;
最先讲一点,外地照片假如不设定容许跨域浏览,canvas.toDataURL是没法画image的,报画布环境污染的错;最先放一张我想转化成的图;

上边载入了二张当地照片,二张外地照片,写了一些文本;在windowsGoogle访问器跑是好的,是吧,照片绘制来,觉得无工作压力;用安卓系统也是好的,很高兴;但是到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运作不成功內容请检索脚本制作之家之前的文章内容或再次访问下边的有关文章内容,期待大伙儿之后多多的适用脚本制作之家!

上一篇:完成checkbox&radio对齐的方式 返回下一篇:没有了