vue + base64 压缩及旋转

1,859 阅读1分钟

前言:移动端拍照及选择图片上传,解决图片太大及手机拍照角度导致照片角度等问题

html代码

<template>
	<div class="twoPic_fdfs">
    	<img v-if='this.PassportImg' :src="this.PassportImg" />
    	<input @change="uploadPhoto($event)" class="change-photo-btn" type='file' accept="image/*"  id="passport" />
   </div>
</template>

js代码

<script>
import {EXIF} from 'exif-js' //获取图片信息
export default {
    data() {
        return {
            Orientation:null,
            PassportImg:'',
        }
    },
    methods:{
        getImgSize(str) {
            //获取base64图片大小,返回KB数字
            var str = str.replace('data:image/jpeg;base64,', '');//这里根据自己上传图片的格式进行相应修改
            
            var strLength = str.length;
            var fileLength = parseInt(strLength - (strLength / 8) * 2);

            // 由字节转换为KB
            var size = "";
            size = (fileLength / 1024).toFixed(2);
            return parseInt(size);

        },
        // 拍照
        uploadPhoto(e) {
            const global = this;
            let id =e.target.id;


            // 利用fileReader对象获取file
            var file = e.target.files[0];

            // var URL = URL || webkitURL;
            //获取照片方向角属性,用户旋转控制
            EXIF.getData(file, function() {
                EXIF.getAllTags(this); 
                global.Orientation = EXIF.getTag(this, 'Orientation');
                //return;
            });
            
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = e => {
                //  alert("压缩前:"+global.getImgSize(e.target.result))
                global.dealImage(e.target.result, 800, (result)=>{
                    //   alert("压缩后:"+global.getImgSize(result))
                  this.PassportImg = result
                   

                },this) 
                // 读取到的图片base64 数据编码 将此编码字符串传给后台即可
            };
        },
    //压缩方法
    dealImage(base64, w, callback,img) {
         const global = this;
        var newImage = new Image()
        //压缩系数0-1之间
        var quality = 0.8
        newImage.src = base64
        newImage.setAttribute('crossOrigin', 'Anonymous')    //url为外域时需要
        var imgWidth, imgHeight
        newImage.onload = function () {
            imgWidth = this.width
            imgHeight = this.height
            var canvas = document.createElement('canvas')
            var ctx = canvas.getContext('2d')
            canvas.width = imgWidth;
            canvas.height = imgHeight;
            //  ========图片旋转==========
                if(global.Orientation && global.Orientation != 1){
                    //  alert('旋转处理,Orientation:'+global.Orientation);
                    switch(global.Orientation){
                        case 6://需要顺时针(向左)90度旋转
                            // alert('需要顺时针(向左)90度旋转');
                            canvas.width = imgHeight;
                            canvas.height = imgWidth;
                            ctx.rotate(Math.PI / 2);
                            ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight);
                            break;
                        case 8://需要逆时针(向右)90度旋转
                            // alert('需要顺时针(向右)90度旋转');
                            canvas.width = imgHeight;
                            canvas.height = imgWidth;
                            ctx.rotate(3 * Math.PI / 2);
                            ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
                            
                            break;
                        case 3://需要180度旋转
                            //  alert('需要180度旋转');
                            ctx.rotate(Math.PI);
                            ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight);
                            break;
                        default:
                            break; 
                    }      
                }else{
                    ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
                }
            // ========图片旋转===========
            
            var ba = canvas.toDataURL('image/jpeg', quality) //压缩语句
            // 如想确保图片压缩到自己想要的尺寸,如要求在50-150kb之间,请加以下语句,quality初始值根据情况自定
            // while (base64.length / 1024 < 150) {
            //     quality -= 0.01;
            //     base64 = canvas.toDataURL("image/jpeg", quality);
            // }
            // 防止最后一次压缩低于最低尺寸,只要quality递减合理,无需考虑
            // while (base64.length / 1024 > 50) {
            //     quality += 0.001;
            //     base64 = canvas.toDataURL("image/jpeg", quality);
            // }
            callback(ba) //必须通过回调函数返回,否则无法及时拿到该值
        }
    }
    }
}
</script>

css代码

<style lang="less">
.twoPic_fdfs{
    font-size: .3rem;
    width: 3rem;
    margin: 20px auto;
    img{
        width: 100%;
    }
}
</style>