利用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实现字体颜色渐变的实现
Mar 09 HTML / CSS
CSS3简单实现照片墙
Dec 12 HTML / CSS
简单总结CSS3中视窗单位Viewport的常见用法
Feb 04 HTML / CSS
CSS3实现多背景模拟动态边框的效果
Nov 08 HTML / CSS
详解CSS3原生支持div铺满浏览器的方法
Aug 30 HTML / CSS
CSS3解析抖音LOGO制作的方法步骤
Apr 11 HTML / CSS
Html5上传图片 移动端、PC端通用代码
Jun 08 HTML / CSS
关于HTML5的22个初级技巧(图文教程)
Jun 21 HTML / CSS
用canvas实现图片滤镜效果附演示
Nov 05 HTML / CSS
用HTML5制作烟火效果的教程
May 12 HTML / CSS
使用HTML5 Canvas API绘制弧线的教程
Mar 22 HTML / CSS
CSS实现切角+边框+投影+内容背景色渐变效果
Nov 01 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/05/16 PHP
解析百度搜索结果link?url=参数分析 (全)
2012/10/09 PHP
PHP生成随机用户名和密码的实现代码
2013/02/27 PHP
Zend的MVC机制使用分析(一)
2013/05/02 PHP
Yii中CArrayDataProvider和CActiveDataProvider区别实例分析
2016/03/02 PHP
Thinkphp和Bootstrap结合打造个性的分页样式(推荐)
2016/08/01 PHP
PhpStorm terminal无法输入命令的解决方法
2016/10/09 PHP
JavaScript 密码强度判断代码
2009/09/05 Javascript
JavaScript 图像动画的小demo
2012/05/23 Javascript
jquery仿QQ商城带左右按钮控制焦点图片切换滚动效果
2013/06/27 Javascript
基于jQuery实现的图片切换焦点图整理
2014/12/07 Javascript
JavaScript实现数字数组正序排列的方法
2015/04/06 Javascript
浅谈js里面的InttoStr和StrtoInt
2016/06/14 Javascript
nodejs个人博客开发第五步 分配数据
2017/04/12 NodeJs
Js中async/await的执行顺序详解
2017/09/22 Javascript
React key值的作用和使用详解
2018/08/23 Javascript
layui 实现加载动画以及非真实加载进度的方法
2019/09/23 Javascript
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
Python的numpy库下的几个小函数的用法(小结)
2019/07/12 Python
Djang的model创建的字段和参数详解
2019/07/27 Python
18个Python脚本可加速你的编码速度(提示和技巧)
2019/10/17 Python
vscode调试django项目的方法
2020/08/06 Python
python判断一个变量是否已经设置的方法
2020/08/13 Python
浅析HTML5 meta viewport参数
2020/10/28 HTML / CSS
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
培训讲师邀请函
2014/01/10 职场文书
工商管理专业毕业生求职信
2014/05/26 职场文书
平面设计专业求职信
2014/08/09 职场文书
工商局局长个人对照检查材料思想汇报
2014/09/23 职场文书
会议接待欢迎标语
2014/10/08 职场文书
2015年民主生活会发言材料
2014/12/15 职场文书
童年读书笔记
2015/06/26 职场文书
大学生社会服务心得体会
2016/01/22 职场文书
2016年社区服务活动总结
2016/04/06 职场文书
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js