思路:

第一步:页面上需要一个不带src 的 img标签

  <img id="img" crossOrigin="anonymous" v-show="false" />

v-show(display:none) 是为了让其加载 但是不显示出来,触发后续的 img.onload事件

第二步:设置img标签,在img.onload事件中获取 file对象

export function urltoFile(imgUrl, imageName) {
  var image = new Image()
  image.setAttribute('crossOrigin', 'Anonymous')
  image.src = imgUrl
  image.onload = function() {
    var base64 = getBase64Image(image)
    document.getElementById('img').src = base64
    //转换base64到file
    var file = btof(base64, imageName)
    console.log('xxxx', file)
    return file
  }
}

 

第三步:

图片的链接地址转化为File对象,需要先转化为canvas,再转化为base64图片

export function getBase64Image(img) {
  var canvas = document.createElement('canvas')
  canvas.width = img.width
  canvas.height = img.height
  var ctx = canvas.getContext('2d')
  ctx.drawImage(img, 0, 0, img.width, img.height)
  var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
  var dataURL = canvas.toDataURL('image/' + ext)
  return dataURL
}

base64图片转化为 Uint8Array (数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。)

 Uint8Array 再次转化为File对象

export function btof(data, fileName) {
  let ext = fileName.split('.')[1]
  const dataArr = data.split(',')
  const byteString = atob(dataArr[1])
  const options = {
    type: 'image/' + ext,
    endings: 'native'
  }
  const u8Arr = new Uint8Array(byteString.length)
  for (let i = 0; i < byteString.length; i++) {
    u8Arr[i] = byteString.charCodeAt(i)
  }
  console.log(fileName.split('.')[0])
  let fileContent = new File([u8Arr], fileName, options)

  return fileContent
}

总结:

完整代码如下:

// imgUrl 转化为File 类型
// url -->base64 -->file
// 注意页面上需要 <img id="img" />
export function urltoFile(imgUrl, imageName) {
  var image = new Image()
  image.setAttribute('crossOrigin', 'Anonymous')
  image.src = imgUrl
  image.onload = function() {
    var base64 = getBase64Image(image)
    document.getElementById('img').src = base64
    //转换base64到file
    var file = btof(base64, imageName)
    console.log('xxxx', file)
    return file
  }
}

export function getBase64Image(img) {
  var canvas = document.createElement('canvas')
  canvas.width = img.width
  canvas.height = img.height
  var ctx = canvas.getContext('2d')
  ctx.drawImage(img, 0, 0, img.width, img.height)
  var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
  var dataURL = canvas.toDataURL('image/' + ext)
  return dataURL
}

export function btof(data, fileName) {
  let ext = fileName.split('.')[1]
  const dataArr = data.split(',')
  const byteString = atob(dataArr[1])
  const options = {
    type: 'image/' + ext,
    endings: 'native'
  }
  const u8Arr = new Uint8Array(byteString.length)
  for (let i = 0; i < byteString.length; i++) {
    u8Arr[i] = byteString.charCodeAt(i)
  }
  console.log(fileName.split('.')[0])
  let fileContent = new File([u8Arr], fileName, options)

  return fileContent
}

注意点: 

1、这种方式一定要在前端给img 设置跨域属性(上述代码已经设置)和服务器端给图片静态资源设置跨域属性 否则 canvas.toDataURL会报错或者会报跨域问题

2、image.setAttribute('crossOrigin', 'Anonymous')需要在 image.src = imgUrl之前 否则 也可能会报错

3、注意最终不是直接let a = urltoFile(xx,xx)就能得到file对象,因为img.onload是异步事件,需要自己去处理

 

 

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐