vue使用Upload组件上传图片

            <Upload class="upload"
                    :show-file-list="false"
                    :action="getUploadUrl"
                    :before-upload="beforeUpLoad"
                    :on-progress="UpLoadOnProgress"
                    :on-error="UploadError"
                    accept="image/*"
                    :on-success="handleUploadSuccess">
                <div class="content"></div>
            </Upload>

其中的几个方法:

        computed: {
            getUploadUrl() {
                return uploadUrl
            }
        },
        methods: {
            handleUploadSuccess(res) {
                this.imgSrc = res.response.data
            },

            UpLoadOnProgress() {
                
            },

            UploadError() {
                
            },

            beforeUpLoad(file) {
                return new Promise((resolve) => {
                    fileUtil.getOrientation(file).then((orient) => {
                        if (orient && orient === 6) {
                            let reader = new FileReader()
                            let img = new Image()
                            reader.onload = (e) => {
                                img.src = e.target.result
                                img.onload = function () {
                                    const data = fileUtil.rotateImage(img, img.width, img.height)
                                    const newFile = fileUtil.dataURLtoFile(data, file.name)
                                    resolve(newFile)
                                }
                            }
                            reader.readAsDataURL(file)
                        } else {
                            resolve(file)
                        }
                    })
                })
            },

        }

问题是这样的,ios中竖屏拍照的时候照片上传之后会旋转90度,因为之前的图片上传组件已经使用了element UI组件,搜索到的方法基本都是在canvas中重绘旋转然后再保存图片上传,但是之后只能上传base64或者blob文件,不能像elementUI一样直接上传File类型的文件,所以这里的思路其实是这样的:

1.使用upload的beforeUpload方法获取到要上传的文件,beforeUpload方法可以返回一个Promise,可以通过resolve file文件将处理之后的文件进行上传

2.使用exif-js库获取图片的Orientation信息,如果Orientation为6,那么这张图片便是ios竖着拍的照片,需要处理,否则直接将原文件上传即可

npm install exif-js --save

3.如果图片文件需要处理,则将文件先转换为Image对象吗,这里用到FileReader,看代码中如何使用

4.然后将Image对象画到canvas画布上,并将画布进行旋转处理

5.将旋转之后的canvas使用toDataURL得到base64数据

6.将base64数据再转化为File文件,上传

下面是处理的时候需要使用的工具方法,可以对比代码将流程捋清楚,fileUtil.js

import EXIF from 'exif-js'

export default {
    getOrientation: (file) => {
        return new Promise((resolve) => {
            EXIF.getData(file, function () {
                const orient = EXIF.getTag(this, 'Orientation')
                resolve(orient)
            })
        })
    },

    dataURLtoFile: (dataurl, filename) => {
        const arr = dataurl.split(',')
        const mime = arr[0].match(/:(.*?);/)[1]
        const bstr = atob(arr[1])
        let n = bstr.length
        let u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, {type: mime});
    },

    rotateImage: (image, width, height) => {
        let canvas = document.createElement('canvas')
        let ctx = canvas.getContext('2d')
        ctx.save()
        canvas.width = height
        canvas.height = width
        ctx.rotate(90 * Math.PI / 180)
        ctx.drawImage(image, 0, -height)
        ctx.restore()
        return canvas.toDataURL("image/jpeg")
    },
}

 

Logo

前往低代码交流专区

更多推荐