利用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 相关文章推荐
css图标制作教程制作云图标
Jan 19 HTML / CSS
通过CSS3的object-fit来调整图片适配尺寸的技巧简介
Feb 27 HTML / CSS
实例讲解CSS3中Transform的perspective属性的用法
Apr 22 HTML / CSS
CSS3实现多背景模拟动态边框的效果
Nov 08 HTML / CSS
HTML5 Web 存储详解
Sep 16 HTML / CSS
Html5上传图片 移动端、PC端通用代码
Jun 08 HTML / CSS
HTML5 File接口在web页面上使用文件下载
Feb 27 HTML / CSS
HTML5未来发展趋势
Feb 01 HTML / CSS
canvas 实现 github404动态效果的示例代码
Nov 15 HTML / CSS
利用Storage Event实现页面间通信的示例代码
Jul 26 HTML / CSS
HTML5 input新增type属性color颜色拾取器的实例代码
Aug 27 HTML / CSS
老生常谈 使用 CSS 实现三角形的技巧(多种方法)
Apr 13 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
摩卡咖啡
2021/03/03 咖啡文化
ThinkPHP中实例Model方法的区别说明
2010/08/21 PHP
php之XML转数组函数的详解
2013/06/07 PHP
PHP 读取大文件并显示的简单实例(推荐)
2016/08/12 PHP
thinkphp 抓取网站的内容并且保存到本地的实例详解
2017/08/25 PHP
jquery HotKeys轻松搞定键盘事件代码
2008/08/30 Javascript
解决3.01版的jquery.form.js中文乱码问题的解决方法
2012/03/08 Javascript
javascript实现分栏显示小技巧附图
2014/10/13 Javascript
JavaScript 继承详解(六)
2016/10/11 Javascript
JS中检测数据类型的几种方式及优缺点小结
2016/12/12 Javascript
JS实现鼠标移上去显示图片或微信二维码
2016/12/14 Javascript
Vue父子组建的简单通信之控制开关Switch的实现
2018/06/04 Javascript
cnpm加速Angular项目创建的方法
2018/09/07 Javascript
对 Vue-Router 进行单元测试的方法
2018/11/05 Javascript
微信小程序实现录音功能
2019/11/22 Javascript
Element InfiniteScroll无限滚动的具体使用方法
2020/07/27 Javascript
Python yield使用方法示例
2013/12/04 Python
python命令行参数解析OptionParser类用法实例
2014/10/09 Python
Python闭包实现计数器的方法
2015/05/05 Python
Python的净值数据接口调用示例分享
2016/03/15 Python
python学习 流程控制语句详解
2016/06/01 Python
教大家玩转Python字符串处理的七种技巧
2017/03/31 Python
python实现超市扫码仪计费
2018/05/30 Python
python网络应用开发知识点浅析
2019/05/28 Python
使用Keras预训练模型ResNet50进行图像分类方式
2020/05/23 Python
Python threading模块condition原理及运行流程详解
2020/10/05 Python
html5 标签
2009/07/16 HTML / CSS
AssertionError 跟一下那个类是 “is – a”的关系
2012/02/21 面试题
小学教师事迹材料
2014/01/13 职场文书
巡警年度自我鉴定
2014/02/21 职场文书
《悯农》教学反思
2014/04/28 职场文书
贸易经济专业自荐书
2014/06/29 职场文书
个人批评与自我批评
2014/10/15 职场文书
个人批评与自我批评材料
2014/10/17 职场文书
监察建议书
2015/02/04 职场文书
小学端午节活动总结
2015/02/11 职场文书