利用canvas实现图片下载功能来实现浏览器兼容问题


Posted in HTML / CSS onMay 31, 2019

前言:项目中需要实现图片下载功能,第一个想到的是使用a标签的download属性来实现,但是在不同浏览器下测试会发现,有的浏览器无效,点击后直接预览图片,所以,上网找到了另外一种兼容不同浏览器的图片下载的方法,那就是利用canvas来处理图片,实现下载;

1.项目中点击事件绑定:

<a href="#" @click.prevent="downloadIamge(imgsrc, name)"><span>{{name}}</span></a>

2.点击事件中操作:

downloadIamge (imgsrc, name) {
      const url = imgsrc
      this.convertUrlToBase64(url).then((base64) => {
        const blob = this.convertBase64UrlToBlob(base64)
        if (getBrowser() === 'IE' || getBrowser() === 'Edge') {
          window.navigator.msSaveBlob(blob, name)
        } else {
          const a = document.createElement('a')
          const body = document.querySelector('body')
          a.download = name || 'image'
          a.href = URL.createObjectURL(blob)
          a.style.display = 'none'
          body.appendChild(a)
          a.click()
          body.removeChild(a)
          window.URL.revokeObjectURL(a.href)
        }
      })
    },

3.this.convertUrlToBase64(url)就是利用canvas和toDataURL把图片转成base64格式并返回

convertUrlToBase64 (url) {
      return new Promise((resolve, reject) => {
        const img = new Image()
        img.crossOrigin = 'Anonymous'
        img.src = url
        img.onload = function () {
          const canvas = document.createElement('canvas')
          canvas.width = img.width
          canvas.height = img.height
          const ctx = canvas.getContext('2d')
          ctx.drawImage(img, 0, 0, img.width, img.height)
          const ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
          const dataURL = canvas.toDataURL('image/' + ext)
          const base64 = {
            dataURL: dataURL,
            type: 'image/' + ext,
            ext: ext
          }
          resolve(base64)
        }
      })
    },

其中:img.crossOrigin = 'Anonymous'是前端对图片的跨域处理;

4.this.convertBase64UrlToBlob(base64)是将图片base64流文件转成blob文件

convertBase64UrlToBlob (base64) {
      const parts = base64.dataURL.split('base64,')
      const contentType = parts[0].split(':')[1]
      const raw = window.atob(parts[1])
      const rawLength = raw.length
      const uInt8Array = new Uint8Array(rawLength)
      for (let i = 0; i < rawLength; i++) {
        uInt8Array[i] = raw.charCodeAt(i)
      }
      return new Blob([uInt8Array], { type: contentType })
    },

5.getBrowser()用来判断浏览器,解决浏览器兼容性问题:

import { getBrowser } from '@/utils/utils'
export function getBrowser () {
  const userAgent = navigator.userAgent
  if (userAgent.indexOf('OPR') > -1) {
    return 'Opera'
  }
  if (userAgent.indexOf('Firefox') > -1) {
    return 'FF'
  }
  if (userAgent.indexOf('Trident') > -1) {
    return 'IE'
  }
  if (userAgent.indexOf('Edge') > -1) {
    return 'Edge'
  }
  if (userAgent.indexOf('Chrome') > -1) {
    return 'Chrome'
  }
  if (userAgent.indexOf('Safari') > -1) {
    return 'Safari'
  }
}

6.如果是IE或者Edge浏览器,可以直接使用window.navigator.msSaveBlob(blob, name)完成下载;

声明:由于ios系统有安全性限制,以上方法在ios上无效;

以上就是记录项目中用到的图片下载,浏览器兼容的问题,涉及到的base64和blob的知识点和原理还不是很清晰,有时间一定要研究一下,整个方法,亲测有效;欢迎测用,与意见反馈。也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3 滤镜 webkit-filter详细介绍及使用方法
Dec 27 HTML / CSS
css3打造一款漂亮的卡哇伊按钮
Mar 20 HTML / CSS
css3旋转木马_动力节点Java学院整理
Jul 12 HTML / CSS
CSS3 linear-gradient线性渐变生成加号和减号的方法
Nov 21 HTML / CSS
CSS 3.0文字悬停跳动特效代码
Oct 26 HTML / CSS
探究 canvas 绘图中撤销(undo)功能的实现方式详解
May 17 HTML / CSS
Html5 实现微信分享及自定义内容的流程
Aug 20 HTML / CSS
HTML5未来发展趋势
Feb 01 HTML / CSS
HTML5标签嵌套规则详解【必看】
Apr 26 HTML / CSS
详解基于canvas的视频遮罩插件
Jan 04 HTML / CSS
基于HTML十秒做出淘宝页面
Oct 24 HTML / CSS
html中两种获取标签内的值的方法
Jun 10 HTML / CSS
HTML5印章绘制电子签章图片(中文英文椭圆章、中文英文椭圆印章)
Jun 03 #HTML / CSS
详解利用canvas实现环形进度条的方法
Jun 12 #HTML / CSS
Html5 实现微信分享及自定义内容的流程
Aug 20 #HTML / CSS
前端canvas动画如何转成mp4视频的方法
Jun 17 #HTML / CSS
详解FireFox下Canvas使用图像合成绘制SVG的Bug
Jul 10 #HTML / CSS
canvas实现有递增动画的环形进度条的实现方法
Jul 10 #HTML / CSS
Html5新增标签与样式及让元素水平垂直居中
Jul 11 #HTML / CSS
You might like
php用数组返回无限分类的列表数据的代码
2010/08/08 PHP
PHP修改session_id示例代码
2014/01/08 PHP
一个完整的php文件上传类实例讲解
2015/10/27 PHP
php 升级到 5.3+ 后出现的一些错误,如 ereg(); ereg_replace(); 函数报错
2015/12/07 PHP
JS是否可以跨文件同时控制多个iframe页面的应用技巧
2007/12/16 Javascript
js综合应用实例简单的表格统计
2013/09/03 Javascript
jquery通过a标签删除table中的一行的代码
2013/12/02 Javascript
表单序列化与jq中的serialize使用示例
2014/02/21 Javascript
ext前台接收action传过来的json数据示例
2014/06/17 Javascript
JQuery动画与特效实例分析
2015/02/02 Javascript
使用命令对象代替switch语句的写法示例
2015/02/28 Javascript
javascript显式类型转换实例分析
2015/04/25 Javascript
JS中递归函数
2016/06/17 Javascript
js 两数组去除重复数值的实例
2017/12/06 Javascript
Nodejs模块的调用操作实例分析
2018/12/25 NodeJs
vue模仿网易云音乐的单页面应用
2019/04/24 Javascript
小程序关于请求同步的总结
2019/05/05 Javascript
[58:23]LGD vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
详解Python中类的定义与使用
2017/04/11 Python
Django视图之ORM数据库查询操作API的实例
2017/10/27 Python
Python3单行定义多个变量或赋值方法
2018/07/12 Python
python微信公众号之关注公众号自动回复
2018/10/25 Python
python手机号前7位归属地爬虫代码实例
2020/03/31 Python
怀俄明州飞钓:Platte River Fly Shop
2017/12/28 全球购物
英国办公用品商店:Office Outlet
2018/04/04 全球购物
Nike澳大利亚官网:Nike.com (AU)
2019/06/03 全球购物
Foot Locker加拿大官网:美国知名运动产品零售商
2019/07/21 全球购物
网络公司美工设计工作个人的自我评价
2013/11/03 职场文书
给交警的表扬信
2014/01/12 职场文书
学生会竞选演讲稿怎么写
2014/08/26 职场文书
奖学金个人总结
2015/03/04 职场文书
毕业生捐书活动倡议书
2015/04/27 职场文书
河童之夏观后感
2015/06/11 职场文书
正能量励志演讲稿三分钟(范文)
2019/07/11 职场文书
React实现动效弹窗组件
2021/06/21 Javascript
一文了解Java动态代理的原理及实现
2022/07/07 Java/Android