方案

创建一个img元素以及一个canvas元素,然后将图片绘制到canvas,再通过canvas的toDataUrl() API可以将图片转base64码,然后模拟点击事件即可下载图片。

注意:在本地或者网站下载外链url图片时涉及到跨域,跨域会暴露自己的隐私,浏览器对跨域请求进行了限制,故需要设置crossOrigin为anonymous来允许跨域,浏览器会为这张图片的请求头附带Origin信息,告诉静态资源服务器,请在响应头中附带Access-Control-Allow-Methods、Access-Control-Allow-Origin,以便浏览器放行。

注意:可以通过下面这种方式获取图片原始网络名称,但是没必要

var fileName = image.src.split(/(\\|\/)/g).pop();

js方式下载

function(){
	  let src = 'http://pic.c-ctrip.com/VacationH5Pic/mice/wechat/ewm01.png';
      let canvas = document.createElement('canvas');
      let img = document.createElement('img');
      // 解决跨域 Canvas 污染问题
      img.setAttribute("crossOrigin", 'Anonymous');
      img.onload = function (e) {
        canvas.width = img.width;
        canvas.height = img.height;
        let context = canvas.getContext('2d');
        //绘制图片
        context.drawImage(img, 0, 0, img.width, img.height);
        canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
        //将canvas转base64码,然后创建一个a连接自动下载图片
        canvas.toBlob((blob) => {
          let link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = 'aaa';
          link.click();
        }, "image/jpeg");
      //将资源链接赋值过去,才能触发img.onload事件
      img.src = src
}

vue方式下载

downloadImage (imgsrc, name) {
  let image = new Image();
  // 解决跨域 Canvas 污染问题
  image.setAttribute("crossOrigin", "anonymous");
  image.onload = function () {
    let canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;
    let context = canvas.getContext("2d");
    context.drawImage(image, 0, 0, image.width, image.height);
    let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
    let a = document.createElement("a"); // 生成一个a元素
    let event = new MouseEvent("click"); // 创建一个单击事件
    a.download = name || "photo"; // 设置图片名称
    a.href = url; // 将生成的URL设置为a.href属性
    a.dispatchEvent(event); // 触发a的单击事件
  }
  //将资源链接赋值过去,才能触发image.onload 事件
  image.src = imgsrc
},

vue项目将图片转base64码后再转成文件类型最后上传腾讯云(以下代码可以忽视,我自己项目的需求)

首先将腾讯云对象配置

import COS from 'cos-js-sdk-v5'
import { getCredential } from '@/api/upload'
import uuid from '@/utils/uuid'

created () {
    this.cos = new COS({
      getAuthorization: (options, callback) => {
        getCredential().then(res => {
          if (res.success) {
            const { result } = res
            // console.log('getCredential', result)
            // eslint-disable-next-line standard/no-callback-literal
            callback({
              TmpSecretId: result.tmpSecretId,
              TmpSecretKey: result.tmpSecretKey,
              XCosSecurityToken: result.sessionToken,
              ExpiredTime: result.expiredTime
            })
          } else {
            this.$message.error(res.msg)
          }
        })
      }
    })
  },
  

第一步,图片下载事件

    downloadImage (url, filename) {
      let that = this
      let img = new Image()
      img.setAttribute('crossOrigin', 'Anonymous')
      img.onload = function () {
        let canvas = document.createElement('canvas')
        canvas.width = img.width
        canvas.height = img.height
        let context = canvas.getContext('2d')
        context.drawImage(img, 0, 0, img.width, img.height)
        canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height)
        // 得到图片的base64编码数据
        let dataURL = canvas.toDataURL('image/png')
        // 第二步,再将图片base64编码数据转成文件对象
        that.myFile = that.dataURLtoFile(dataURL, filename)
        canvas = null
        setTimeout(() => {
          // 第三,将图片文件对象上传腾讯云
          that.uploadTest(that.myFile)
        }, 100)
      }
      img.src = url
    },

第二步,将base64转换为文件

//第二步,将base64转换为文件
    dataURLtoFile (dataurl, filename) {
      let arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new File([u8arr], filename, { type: mime })
    },

第三,将图片文件对象上传腾讯云

// 第三,将图片文件对象上传腾讯云
    uploadTest (file) {
      const uid = uuid()
      const extName = this.getExtName(file.name)
      const fileName = `${uid}.${extName}`
      this.cos.putObject(
        {
          Bucket: this.$CONFIG.Bucket,
          Region: this.$CONFIG.Region,
          Key: fileName,
          Body: file, // 上传文件对象
          onProgress: progressData => {
            // this.progress = progressData.percent
            // console.log(JSON.stringify(progressData))
          }
        },
        (err, data) => {
          if (err) {
            this.$notification.error({
              message: '文件上传错误',
              description: err.Message
            })
          } else {
            const url = `http://${data['Location']}`
            console.log('图片上传完成', url)
          }
          this.loading = false
        }
      )
    },
    /**
     * 获取后缀名
     */
    getExtName (fileName) {
      const index = fileName.lastIndexOf('.')
      if (index > -1) {
        return fileName.substring(index + 1)
      } else {
        return ''
      }
    },

参考01
参考02
参考03
参考04
参考05

Logo

前往低代码交流专区

更多推荐