图片压缩上传【前端】

      先讲大致流程监听input表单变化读取文件 -> file.size若超出大小 -> canvas图片压缩 -> 用Blob,base64转二进制对象 -> 二进制对象转文件 -> formData 上传

html部分

使用,监听表单变化,触发图片上传

let compress = new Compress()
compress.getImgData(e, (res) => {
    this.onBeforceUpload(res) // 上传
    this.$refs.upload.value = null // 清空表单
})

图片文件读取,判断是否需要压缩

getImgData(e, limit, callback) {
        let file = event.target.files[0]
        // 图片格式
        if (['jpeg', 'png', 'gif', 'jpg'].indexOf(this.fileType.split('/')[1]) < 0) {
            return { error: '图片格式错误' }
        }

        // 在部分ios压缩会有问题
        let u = navigator.userAgent
        let isIos = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
        if (isIos) {
            callback(this.file)
            return
        }

        let r = new FileReader()
        r.readAsDataURL(file)
        r.onload = () => {
            if (r.result) {
                let base64 = r.result
                let maxSize = limit * 1024
                let fileSize = file.size / 1024
                if (limit && fileSize > maxSize) {
                    // 一位小数(不四舍五入)
                    this.getCompress(base64).then((res) => {
                        let upfile = processData(res)
                        callback(upfile)
                    })
                } else {
                    callback(file)
                }
            }
        }
    }

使用canvas 绘制,输出为base64

getCompress(dataURL) {
	return new Promise((resolve, reject) => {
		let that = this
		const img = new window.Image()
		img.onload = function() {
			let [drawWidth, drawHeight] = [this.naturalWidth, this.naturalHeight]
			let maxSide = Math.max(drawWidth, drawHeight)
            // 最长的边大于1024,则等比缩放长边为1024
			if (maxSide > 1024) {
				let minSide = Math.min(drawWidth, drawHeight)
				minSide = minSide / maxSide * 1024
				maxSide = 1024
				if (drawWidth > drawHeight) {
					drawWidth = maxSide
					drawHeight = minSide
				} else {
					drawWidth = minSide
					drawHeight = maxSide
				}
			}

			let canvas = document.createElement('canvas')
			canvas.width = drawWidth
			canvas.height = drawHeight
			let context = canvas.getContext('2d')
			context.clearRect(0, 0, drawWidth, drawHeight)
			context.drawImage(this, 0, 0, drawWidth, drawHeight)

			resolve(canvas.toDataURL(that.fileType, 0.8)) // 这里0.8可以选择自定义
		}
		img.src = dataURL
	})
}

将base64 转为文件

processData(dataURL) {
    // 这里使用二进制方式处理dataUrl
    const bytes = window.atob(dataURL.split(',')[1])
    const ab = new ArrayBuffer(bytes.length)
    const ia = new Uint8Array(ab)
    const type = this.file.type
    const imgFile = this.file

    for (let i = 0, j = bytes.length; i < j; i++) {
        ia[i] = bytes.charCodeAt(i)
    }

    let blob

    try {
        blob = new Blob([ia], { type })
    } catch (error) {
        window.BlobBuilder = window.BlobBuilder ||
            window.WebKitBlobBuilder ||
            window.MozBlobBuilder ||
            window.MSBlobBuilder
        if (error.name === 'TypeError' && window.BlobBuilder) {
            let Builder = window.BlobBuilder
            const builder = new Builder()
            builder.append(ab)
            blob = builder.getBlob(type)
        } else {
            // Toast.error("版本过低,不支持上传图片", 2000, undefined, false);
            throw new Error('版本过低,不支持上传图片')
        }
    }

    // blob 转file
    const fileOfBlob = new File([blob], imgFile.name, { type })

    return fileOfBlob
}


 

你可能感兴趣的:(javascript)