zoukankan      html  css  js  c++  java
  • vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理

    一、前言

      三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习。

      图片的上传之前都是用的插件(ajaxupload),或者传统上传图片的方式,各有利弊:插件的问题是依赖jq并且会使系统比较臃肿,还有传统的web开发模式 前后端偶尔在一起及对用户体验要求低,现在公司采用webpack+vue+restfullApi开发模式 前后端完全分离,遵从高内聚,低偶尔的原则,开发人员各司其职,一则提升开发效率(从长期来看,短期对于很多开发人员需要有个适应的过程,特别是初中级的前端处理业务逻辑方面的能力比较欠缺),二则提升用户体验。今天分享下在项目开发中写的的图片上传 vue组件。

    二、处理问题

      这里用h5做图片上传考虑到浏览器支持的问题,这里考虑的场景是在做webapp的时候

      1.移动web图片上传还包括拍摄上传,但是在移动端会出现拍摄的照片会旋转,处理这个问题需要得到图片旋转的情况,可以用exif.js来获取,具体可以参看文档

      2.图片压缩

      3.旋转

    三、代码

    1组件代码

    <template>
        <div>
            <input type="file" style="display: none;" id="img-upload" multiple accept="image/*" @change="uploadImg($event)"/>
        </div>
    </template>
    <script>
        import EXIF from '../../../Resource/Global/Js/exif'
        export default{
            name:"image-html5-upload",
            props:{
                imgArr:{
                    type:Array,
                    twoWay: true,
                    default:Array
                },
                imgNumLimit:{//一次最多可以上传多少张照片
                    type:Number,
                    default:4
                }
            },
            methods:{
                "uploadImg": function(e){
                    let tag = e.target;
                    let fileList = tag.files;
                    let imgNum = fileList.length;
                    let _this = this;
                    _this.imgArr = [];//图片数据清零
                    if(this.imgArr.length + imgNum > this.imgNumLimit){
                        alert('一次最多上传'+this.imgNumLimit+'张图片!');
                        return;
                    }
                    var Orientation;
                    for(let i=0;i<imgNum;i++){
                        EXIF.getData(fileList[i], function(){
                            Orientation = EXIF.getTag(fileList[i], 'Orientation');
                        });
                        let reader = new FileReader();
                        reader.readAsDataURL(fileList[i]);
                        reader.onload = function(){
                            var oReader = new FileReader();
                            oReader.onload = function(e) {
                                var image = new Image();
                                image.src = e.target.result;
                                image.onload = function() {
                                    var expectWidth = this.naturalWidth;
                                    var expectHeight = this.naturalHeight;
                                    if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
                                        expectWidth = 800;
                                        expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
                                    } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
                                        expectHeight = 1200;
                                        expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
                                    }
                                    var canvas = document.createElement("canvas");
                                    var ctx = canvas.getContext("2d");
                                    canvas.width = expectWidth;
                                    canvas.height = expectHeight;
                                    ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
                                    var base64 = null;
                                    //修复ios上传图片的时候 被旋转的问题
                                    if(Orientation != "" && Orientation != 1){
                                        switch(Orientation){
                                            case 6://需要顺时针(向左)90度旋转
                                                _this.rotateImg(this,'left',canvas);
                                                break;
                                            case 8://需要逆时针(向右)90度旋转
                                                _this.rotateImg(this,'right',canvas);
                                                break;
                                            case 3://需要180度旋转
                                                _this.rotateImg(this,'right',canvas);//转两次
                                                _this.rotateImg(this,'right',canvas);
                                                break;
                                        }
                                    }
                                    base64 = canvas.toDataURL("image/jpeg", 0.8);
                                    if(fileList[i].size / 1024000 > 1){
                                        _this.imgScale(base64, 4)
                                    }else{
                                        _this.imgArr.push({"src": base64});
                                    }
                                    console.log(JSON.stringify(_this.imgArr));
                                };
                            };
                            oReader.readAsDataURL(fileList[i]);
                        }
                    }
                },
                "imgScale": function(imgUrl,quality){
                    let img = new Image();
                    let _this = this;
                    let canvas = document.createElement('canvas');
                    let cxt = canvas.getContext('2d');
                    img.src = imgUrl;
                    img.onload = function(){
                        //缩放后图片的宽高
                        let width = img.naturalWidth/quality;
                        let height = img.naturalHeight/quality;
                        canvas.width = width;
                        canvas.height = height;
                        cxt.drawImage(this, 0, 0, width, height);
                        _this.imgArr.push({"src": canvas.toDataURL('image/jpeg')});
                    }
                },
                "rotateImg":function (img, direction,canvas) {//图片旋转
                    var min_step = 0;
                    var max_step = 3;
                    if (img == null)return;
                    var height = img.height;
                    var width = img.width;
                    var step = 2;
                    if (step == null) {
                        step = min_step;
                    }
                    if (direction == 'right') {
                        step++;
                        step > max_step && (step = min_step);
                    } else {
                        step--;
                        step < min_step && (step = max_step);
                    }
                    var degree = step * 90 * Math.PI / 180;
                    var ctx = canvas.getContext('2d');
                    switch (step) {
                        case 0:
                            canvas.width = width;
                            canvas.height = height;
                            ctx.drawImage(img, 0, 0);
                            break;
                        case 1:
                            canvas.width = height;
                            canvas.height = width;
                            ctx.rotate(degree);
                            ctx.drawImage(img, 0, -height);
                            break;
                        case 2:
                            canvas.width = width;
                            canvas.height = height;
                            ctx.rotate(degree);
                            ctx.drawImage(img, -width, -height);
                            break;
                        case 3:
                            canvas.width = height;
                            canvas.height = width;
                            ctx.rotate(degree);
                            ctx.drawImage(img, -width, 0);
                            break;
                    }
                }
            }
        }
    </script>

    2.使用方法

    <template>
        <div>
            <div class="album-img-list">
                <ul>
                    <li v-for="img in imgList"><div class="album-bg-img"><img  :src='img.src'> </div></li>
    
                </ul>
            </div>
            <div class="album">
                <label for="img-upload">上传照片</label>
                    <image-html5-upload :img-arr.sync="imgList"></image-html5-upload>
            </div>
        </div>
    </template>

    本文版权归作者(谢俊)和博客园所有,欢迎转载,转载请标明出处。

    原文地址:http://www.cnblogs.com/net-xiejun/

    微信开发群C#.NETWEB程序开发交流

    完整源码下载:https://github.com/xiejun-net/weixin

    公众账号:

  • 相关阅读:
    网络抓包工具使用
    JAVA 原子操作类
    guava collection/cache初探
    MiniGUI
    Cookie
    System V IPC
    SQLite交叉编译
    NCurses交叉编译
    双向循环链表
    VMware安装Windows Server 2008
  • 原文地址:https://www.cnblogs.com/net-xiejun/p/5901598.html
Copyright © 2011-2022 走看看