资讯专栏INFORMATION COLUMN

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

NSFish / 1156人阅读

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

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

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

{{name}}

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的知识点和原理还不是很清晰,有时间一定要研究一下,整个方法,亲测有效;欢迎测用,与意见反馈。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104230.html

相关文章

  • H5 canvas生成图片并上传文件转成PDF下载canvas文字排版

    摘要:将预览的图片上传,后端生成,在管理系统中下载。技术要点文字排版设置指定背景颜色引入外部字体绘制文字图片将生成的图片转成上传这里根据后端协商,此处后端要求将图片生成,并点击批量下载实现步骤文字排版在一般容器中,如果要实现文字的排版很容易。 最近遇到一个业务需求,在小程序端定制预览功能,并在预览的图片中使用指定的外部字体。将预览的图片上传OSS,后端生成PDF,在管理系统中下载。但是………...

    canopus4u 评论0 收藏0
  • 前端动画调研-V1

    摘要:支持动画状态的,在动画开始,执行中,结束时提供回调函数支持动画可以自定义贝塞尔曲线任何包含数值的属性都可以设置动画仓库文档演示功能介绍一定程度上,也是一个动画库,适用所有的属性,并且实现的能更方便的实现帧动画,替代复杂的定义方式。 动画调研-V1 前言:动画从用途上可以分为两种,一种是展示型的动画,类似于一张GIF图,或者一段视频,另一种就是交互性的动画。这两种都有具体的应用场景,比如...

    ddongjian0000 评论0 收藏0
  • 移动端H5图片上传的那些坑

    摘要:上周做一个关于移动端图片压缩上传的功能。利用,进行图片的压缩,得到图片的的值上传文件。 上周做一个关于移动端图片压缩上传的功能。期间踩了几个坑,在此总结下。 大体的思路是,部分API的兼容性请参照caniuse: 利用FileReader,读取blob对象,或者是file对象,将图片转化为data uri的形式。 使用canvas,在页面上新建一个画布,利用canvas提供的API,...

    Seay 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<