zoukankan      html  css  js  c++  java
  • 项目回顾1-图片上传-form表单还是base64-前端图片压缩

    第一个项目终于上线了,是一个叫亲青筹的公益众筹平台,微信端,电脑端还有后台界面大部分都是我完成的,几个月过来,感觉收获了很多,觉得要总结一下。

    首先想到的是图片上传的问题。在通常表单数据都是ajax上传的情况下,为了上传图片而去使用form表单感觉很蠢。然后那时候也没有想到用jquery form插件。

    后台的同事给的方案是用iframe里写一个form表单,然后上传图片之后自动提交表单,他将图片在服务器上的地址以跳转页url的一部分,我再来截取的方式。

    方案一:iframe+form表单

        <form action="/user/uploadIdCard.do" class="fileForm picUpload" enctype="multipart/form-data" method="post">
            <input type="file" id="uploadPic" name="file">
            <label for="uploadPic" id="fileBtn">
                +
                <img src="" />
            </label>
            <input type="text" name="turnUrl" class="turnUrl">
        </form>
        $(".turnUrl").val(window.location.pathname);
        $("#uploadPic").on('change', function(event) {
            event.preventDefault();
            $("form").submit();
        });

    在需要上传图片的界面引入iframe,在调用公用库里的iframe方法,获得图片的url并且把图片显示在iframe中

    // 提取iframe里的路径
    function iframe(el) {
        var baseurl = "";
        var code, filePath;
        var place = $(el)[0].contentWindow.location.search;
        console.log(place);
        if (place) {
            code = place.match(/code=d+/)[0].substr(5);
            if (place.match(/filepath=S+/)) {
                filePath = place.match(/filepath=S+/)[0].substr(9);
            }
            $(el).contents().find(".tip").css('color', '#d0021b');
            console.log(filePath);
            switch (code) {
                case "200":
                    $(el).contents().find(".tip").text('上传成功');
                    $(el).contents().find(".tip").css('color', '#55a012');
                    $(el).contents().find("#fileBtn>img").show().attr("src", baseurl + "/" + filePath);
                    return "/" + filePath;
                case "206":
                    $(el).contents().find(".tip").text('文件过大');
                    break;
                case "207":
                    $(el).contents().find(".tip").text('文件类型错误');
                    break;
                case "208":
                    $(el).contents().find(".tip").text('系统错误');
            }
        }
    }

    方案二:后来发现这样的做法有两个问题,一个是用户发的图片太大,后台没有做压缩(后台的同事太忙了,为了迁就他们,就我们前端做压缩了)。第二个是,上传图片成功之后,图片显示在iframe上,这样需要一定的反应时间,使用者有时候会反映图片传不上去,其实只是后台还没有返回……

    于是决定用base64上传到后台的方式

        <input type="file" id="uploadPic" name="file">
        <label for="uploadPic" id="fileBtn">
            +
            <img class="showPic" src="" />
        </label>
        <span class="tip">请上传图片,大小在2M以内<br/>(图片类型可为jpg,jepg,png,gif,bmp)<br/>推荐图片比例为640*400</span>
        <input type="text" name="turnUrl" class="turnUrl">
        <canvas id="uploadImg" style="display:none"></canvas>

    结构和原来差不多,只是多了一个canvas

        $("#uploadPic").on('change', function(event) {
            event.preventDefault();
            console.log($(this)[0].files);
            var file = $(this)[0].files[0];
            if(file.size>2097152){
                alert("上传图片请小于2M");
                return false;
            }        if (!/image/w+/.test(file.type)) {
                alert("文件必须为图片!");
                return false;
            }
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function(e) {
                    createCanvas(this.result);
                }
        });
    
        function createCanvas(src) {
            var canvas = document.getElementById("uploadImg");
            var cxt = canvas.getContext('2d');
            canvas.width = 640;
            canvas.height = 400;
            var img = new Image();
            img.src = src;
            img.onload = function() {
                // var w=img.width;
                // var h=img.height;
                // canvas.width= w;
                // canvas.height=h;
                cxt.drawImage(img, 0, 0,640,400);
                //cxt.drawImage(img, 0, 0);
                $(".showPic").show().attr('src', canvas.toDataURL("image/jpeg", 0.9));
                $.ajax({
                    url: "/front/uploadByBase64.do",
                    type: "POST",
                    data: {
                        "imgStr": canvas.toDataURL("image/jpeg", 0.9).split(',')[1]
                    },
                    success: function(data) {
                        console.log(data);
                        $(".showPic").show().attr('data-url',"/"+ data.url);
                    }
                });
            }
        }

    1.首先是用的input的file文件的信息,判断文件大小file.size,以及文件是否为图片file.type

    2.再通过html5的FileReader接口来获得这个图片的base64数据

    3.将这个base64传入canvas中,作为一张图的src,这时候可以设置图片的分辨率大小,保证上传的图都是统一的分辨率。当然也可以按照图片原来的大小。

    4.在ajax之前,把处理后的base64直接显示出来(这样用户就可以立刻看到自己上传的图片),再将 canvas.toDataURL("image/jpeg", 0.9).split(',')[1] (类型为image/jpeg,就可以用第二个参数来设置画质了)传到后台对应的接口

    5.再将后台返回的url 绑在图片的data-url属性上,在ajax上交整个表单时获取这个data-url就好了,这样用户可以最快时间看到,而url其实还在ajax到后台的过程中

    后记:这两个方案都有一个问题,会给后台上传很多冗余图片。不过后台的同事貌似没什么意见,囧。

    实际效果是这样的 http://www.qqchou.org/qqcweb/pages/photoIframe.html 

  • 相关阅读:
    leetcode 48. Rotate Image
    leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点) 、26/80. Remove Duplicates from Sorted ArrayI、II
    leetcode 263. Ugly Number 、264. Ugly Number II 、313. Super Ugly Number 、204. Count Primes
    leetcode 58. Length of Last Word
    安卓操作的一些问题解决
    leetcode 378. Kth Smallest Element in a Sorted Matrix
    android studio Gradle Build速度加快方法
    禁用gridview,listview回弹或下拉悬停
    Android Studio找不到FragmentActivity类
    安卓获取ListView、GridView等滚动的距离(高度)
  • 原文地址:https://www.cnblogs.com/wzls/p/5714273.html
Copyright © 2011-2022 走看看