js图片上传是用二进制串还是表单提交啊
发布于 4 个月前 作者 fruit-memory 1224 次浏览 来自 问答

有人能给分析下吗? 我只知道小图片用base64上传,但是大图片不知道咋搞。 我的想法是转二进制上传,但是我见到有的人是只用的表单,有的人是用二进制加表单 还有一个奇怪的东西,png图片转canvas压缩过的或者二进制都会变得比base64大 image.png 第一个是canvas压缩过的跟base64对比,第二个是二进制跟base64对比的 代码

class UploadImg extends Component {
  static defaultProps = {
    style: {
      width: '600px',
      height: '400px'
    },
    duration: 6,
    imgPlugin: {
      maxSize: 2,
      quality: 0.75,
      width: 600,
      height: 600
    },
    requset: function() {}
  }
  openNotification = (index, type) => {
    const {maxSize} = this.props.imgPlugin
    let _description = {
      type: `第${index + 1}张图不是jpg/png/gif/jpg格式的图片!`,
      size: `第${index + 1}张照片太大了,我们约定${maxSize}以内好不好`
    }
    notification['warning']({
      message: '出错啦!!!',
      description: _description[type],
      duration: this.props.duration
    })
  }
  canvasDataURL = (src, type, width, height, quality) => {
    let newImg = new Image()
    newImg.src = src
    document.getElementsByClassName('avatar')[0].src = src
    let imgWidth, imgHeight, base64
    let promise = new Promise(resolve => {
      newImg.onload = () => {
        let img = document.createElement('img')
        img.style.width='500px'
        img.src = newImg.src
        imgWidth = img.width*quality
        imgHeight = img.height*quality
        let canvas = document.createElement('canvas')
        canvas.width = imgWidth
        canvas.height = imgHeight
        let ctx = canvas.getContext('2d')
        ctx.clearRect(0, 0, imgWidth, imgHeight)
        ctx.drawImage(img, 0, 0,imgWidth,imgHeight)
        base64 = canvas.toDataURL(type, quality)
        document.getElementsByClassName('avatar')[0].src = base64
        resolve(base64)
      }
    })
    return promise
  }
  convertCanvasToBlob = (src, type, width, height, quality) => {
    return new Promise((resolve, reject) => {
      this.canvasDataURL(src, type, width, height, quality).then(res => {
        var base64 = res
        var code = window.atob(base64.split(',')[1])
        var aBuffer = new window.ArrayBuffer(code.length)
        var uBuffer = new window.Uint8Array(aBuffer) //Uint8Array:8位无符号整数,长度1个字节。

        for (var i = 0; i < code.length; i++) {
          uBuffer[i] = code.charCodeAt(i)
        }
        var Builder = window.WebKitBlobBuilder || window.MozBlobBuilder
        if (Builder) {
          var builder = new Builder()
          builder.append(aBuffer)
          console.log(builder.getBlob(type))
          //resolve (builder.getBlob(type))
        } else {
            console.log(new window.Blob([aBuffer], {type: type}))
            //resolve(new window.Blob([aBuffer], {type: type}))
        }
        resolve(uBuffer)
      })
    })
  }

  compress = (file, width, height, canvas) => {}

  getFileInfo = e => {
    const {maxSize, width, height, quality} = this.props.imgPlugin
    const files = e.target.files
    for (let i = 0; i < files.length; ++i) {
      if (!/(jpeg|png|gif|jpg)$/.test(files[i].type)) {
        this.openNotification(i, 'type')
        return
      }
      /*if (files[i].size / 1024 / 1024 > maxSize) {
        this.openNotification(i, 'size')
        return
      }*/
      let img = new FileReader()
      img.readAsDataURL(files[i])
      img.onload = () => {
        this.canvasDataURL(img.result, files[i].type, width, height, quality).then(res => {
          console.log(res.length *100/ img.result.length + '%')
          console.log(res.length ,img.result.length )
        })
        this.convertCanvasToBlob(img.result, files[i].type, width, height, quality).then(res => {
          console.log(res.length *100/ img.result.length + '%')
          console.log(res.length ,img.result.length )
        })
      }
    }
  }
  render() {
    const {style} = this.props
    return (
      <div>
        <input type="file" onChange={this.getFileInfo} multiple="multiple" accept="image/*"/>
        <img className="avatar" style={{width: '100%', height: '100%'}} />
      </div>
    )
  }
}

5 回复

有些地方对象属性名称和变量重名,大家默认变量名前面加了下划线就好,我没改

1、考虑兼容性:表单提交上传; 2、考虑交互:二进制上传,上传前可预览&裁剪等各种操作;

@x-cold 谢谢,我就是想用第二种方法,但是不知道他们的区别

@x-cold 我觉得我还不够格,此处应该加个表情笑cry

回到顶部