Using canvas to download pictures to realize browser compatibility

In the project, we need to realize the function of picture download. The first thought is to use the download attribute of a tag. However, when we test it in different browsers, we will find that some browsers are invalid and preview pictures directly after clicking. Therefore, we find another method of picture download compatible with different browsers on the Internet, that is to use canvas to process pictures and realize download;

1. Click event binding in the project:

<a href="#" @click.prevent="downloadIamge(imgsrc, name)"><span>{{name}}</span></a>

2. Click the action in the event:

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)
        }
      })
    },

Analysis:
3.this.convertUrlToBase64(url) is to use canvas and toDataURL to convert pictures to base64 format and return

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)
        }
      })
    },

Among them: img.crossOrigin = 'Anonymous' is the cross domain processing of pictures by the front end;

4.this.convertBase64UrlToBlob(base64) is to convert the picture base64 stream file to a blob file

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() is used to judge the browser and solve the browser compatibility problem:

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. If it is IE or Edge browser, you can directly use window.navigator.msSaveBlob(blob, name) to complete the download;

Declaration: because ios system is limited by security, the above methods are invalid on ios;

The above is the problem of image download and browser compatibility used in the recording project. The knowledge points and principles of base64 and blob involved are not very clear. If you have time, you must study the whole method. The pro test is effective. Welcome to test and feedback.

Tags: Javascript IE iOS Attribute Firefox

Posted on Sat, 02 Nov 2019 21:36:49 -0700 by marsupillami