利用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系列之3D制作方法案例
Aug 14 HTML / CSS
css3如何绘制一个圆圆的loading转圈动画
Jan 09 HTML / CSS
Html5 postMessage实现跨域消息传递
Mar 11 HTML / CSS
html5中为audio标签增加停止按钮动作实现方法
Jan 04 HTML / CSS
仿CSDN Blog返回页面顶部功能实现原理及代码
Jun 30 HTML / CSS
HTML5 Canvas锯齿图代码实例
Apr 10 HTML / CSS
HTML5 canvas基本绘图之绘制曲线
Jun 27 HTML / CSS
HTML5操作WebSQL数据库的实例代码
Aug 26 HTML / CSS
利用canvas实现图片压缩的示例代码
Jul 17 HTML / CSS
html5 canvas的绘制文本自动换行的示例代码
Sep 17 HTML / CSS
html5实现九宫格抽奖可固定抽中某项奖品
Jun 15 HTML / CSS
使用canvas对video视频某一刻截图功能
Sep 25 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
如何使用脚本模仿登陆过程
2006/11/22 PHP
smarty模板中拼接字符串的方法
2014/02/14 PHP
php判断数组中是否存在指定键(key)的方法
2015/03/17 PHP
PHP使用NuSOAP调用Web服务的方法
2015/07/18 PHP
深入讲解PHP Session及如何保持其不过期的方法
2015/08/18 PHP
PHP面向对象程序设计__tostring()和__invoke()用法分析
2019/06/12 PHP
Javascript 继承实现例子
2009/08/12 Javascript
『jQuery』取指定url格式及分割函数应用
2013/04/22 Javascript
js中通过split函数分割字符串成数组小例子
2013/09/21 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
vue.js事件处理器是什么
2017/03/20 Javascript
Node.js中环境变量process.env的一些事详解
2017/10/26 Javascript
详解Vue2.0配置mint-ui踩过的那些坑
2018/04/23 Javascript
Node.js连接Sql Server 2008及数据层封装详解
2018/08/27 Javascript
Layer+Echarts构建弹出层折线图的方法
2019/09/25 Javascript
[01:26]DOTA2荣耀之路2:iG,China
2018/05/24 DOTA
python求素数示例分享
2014/02/16 Python
Python中的装饰器用法详解
2015/01/14 Python
Python从list类型、range()序列简单认识类(class)【可迭代】
2019/05/31 Python
对django 2.x版本中models.ForeignKey()外键说明介绍
2020/03/30 Python
安装pyecharts1.8.0版本后导入pyecharts模块绘图时报错: “所有图表类型将在 v1.9.0 版本开始强制使用 ChartItem 进行数据项配置 ”的解决方法
2020/08/18 Python
利用python查看数组中的所有元素是否相同
2021/01/08 Python
HTML5页面嵌入小程序没有返回按钮及返回页面空白的问题
2020/05/28 HTML / CSS
台湾乐天市场:日本No.1的网路购物网站
2017/03/22 全球购物
Boston Proper官网:美国女装品牌
2017/10/30 全球购物
Fanatics英国官网:美国体育电商
2018/11/06 全球购物
英国健身超市:Fitness Superstore
2019/06/17 全球购物
阿里巴巴的Oracle DBA笔试题答案-SQL tuning类
2016/04/03 面试题
生产现场工艺工程师岗位职责
2013/11/28 职场文书
民生工作实施方案
2014/05/31 职场文书
机电系毕业生求职信
2014/07/11 职场文书
公务员群众路线专题民主生活会发言材料
2014/09/17 职场文书
小学生2015教师节演讲稿
2015/03/19 职场文书
Python实现科学占卜 让视频自动打码
2022/04/09 Python