利用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旋转动画实例代码
Sep 11 HTML / CSS
表单button的outline在firefox浏览器下的问题
Dec 24 HTML / CSS
CSS实现进度条和订单进度条的示例
Nov 05 HTML / CSS
使用CSS3制作版头动画效果
Dec 24 HTML / CSS
详解Html5原生拖拽操作
Jan 12 HTML / CSS
HTML5中语义化 b 和 i 标签
Oct 17 HTML / CSS
仿酷狗html5手机音乐播放器主要部分代码
May 15 HTML / CSS
html5 自定义播放器核心代码
Dec 20 HTML / CSS
HTML5实现晶莹剔透的雨滴特效
May 14 HTML / CSS
HTML5+Canvas+CSS3实现齐天大圣孙悟空腾云驾雾效果
Apr 26 HTML / CSS
使用CSS实现一个搜索引擎的原理解析
Sep 25 HTML / CSS
使用CSS实现音波加载效果
May 07 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处理换行符的问题 \r\n
2013/06/13 PHP
显示程序执行时间php函数代码
2013/08/29 PHP
2款PHP无限级分类实例代码
2015/11/11 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
2016/03/21 PHP
PHP简单获取多个checkbox值的方法
2016/06/13 PHP
CodeIgniter框架数据库基本操作示例
2018/05/24 PHP
JavaScript URL参数读取改进版
2009/01/16 Javascript
jQuery+slidereveal实现的面板滑动侧边展出效果
2015/03/14 Javascript
浅谈JavaScript for循环 闭包
2016/06/22 Javascript
JavaScript事件详细讲解
2016/06/27 Javascript
jQuery实现的仿百度,仿谷歌搜索下拉框效果示例
2016/12/30 Javascript
Bootstrap table使用方法记录
2017/08/23 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
vue+elementUI实现表单和图片上传及验证功能示例
2019/05/14 Javascript
vue elementUI table 自定义表头和行合并的实例代码
2019/05/22 Javascript
Python 深入理解yield
2008/09/06 Python
详解python中xlrd包的安装与处理Excel表格
2016/12/16 Python
python实现人脸识别经典算法(一) 特征脸法
2018/03/13 Python
Django forms组件的使用教程
2018/10/08 Python
pygame游戏之旅 调用按钮实现游戏开始功能
2018/11/21 Python
python lxml中etree的简单应用
2019/05/10 Python
浅谈django url请求与数据库连接池的共享问题
2019/08/29 Python
python读取tif图片时保留其16bit的编码格式实例
2020/01/13 Python
Python devel安装失败问题解决方案
2020/06/09 Python
Python 实现键盘鼠标按键模拟
2020/11/18 Python
CSS3制作皮卡丘动画壁纸的示例
2020/11/02 HTML / CSS
CSS3 实现发光边框特效
2020/11/11 HTML / CSS
HTML5 Canvas中使用用路径描画圆弧
2015/01/01 HTML / CSS
Ellesse英国官网:意大利高级运动品牌
2019/07/23 全球购物
金融专业个人的自我评价
2013/10/18 职场文书
2014年销售工作总结与计划
2014/12/01 职场文书
教师个人事迹材料
2014/12/17 职场文书
小学毕业教师寄语
2019/06/21 职场文书
Python 循环读取数据内存不足的解决方案
2021/05/25 Python
Django与数据库交互的实现
2021/06/03 Python
mysql查找连续出现n次以上的数字
2022/05/11 MySQL