首页前端开发HTML关于canvas.toDataURL 在iOS运行失败的问题解决

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

时间2024-01-25 07:03:18发布访客分类HTML浏览926
导读:收集整理的这篇文章主要介绍了关于canvas.toDataURL 在iOS运行失败的问题解决 ,觉得挺不错的,现在分享给大家,也给大家做个参考。 最近做了一个海报生成的组件,需要drawimage到画布上,image来源包括本地和...
收集整理的这篇文章主要介绍了关于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 hereimg.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 tooif ( img.complete || img.complete === undefined ) {
        img.src = "data:image/gif;
    base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
        img.src = src;
}
    

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

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

canvas.toDataURL

若转载请注明出处: 关于canvas.toDataURL 在iOS运行失败的问题解决
本文地址: https://pptw.com/jishu/586250.html
canvas绘制图片drawImage使用方法 canvas 绘图时位置偏离的问题解决

游客 回复需填写必要信息