HTML5移动端图片浏览上传

本文介绍了一种利用HTML5 canvas实现的前端图片压缩方法,通过直接操作base64字符完成图片的压缩,相较于后端处理,该方法能更快地实现图片压缩,并减少服务器负载。

HTML页面中图片底层是base64格式字符串显示的,HTML5中可以直接操作base64字符,完成图片的浏览压缩等,比后台图片压缩效率高,速度快,但占用的是客服端资源。
PHP,Java,.Net都有相应语法把base64转成二进制在转换成相应文件。
实例:
这里写图片描述

<!DOCTYPE html>
<html>
<head>
    <!-- 移动端适配   全屏  支持屏幕放大缩小的倍率 -->
    <meta name="full-screen" content="yes">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>图片上传</title>
    <style type="text/css">
        #file{position: absolute;width: 100px;left: 50%;margin-left: -50px;opacity:0;margin-top: -35px;}
        #filePicker{font-size:14px;text-align:center;height: 25px;line-height: 25px;border: 1px solid #ddd;border-radius:5px;color:#f55;width: 100px;margin: 10px auto;}
        #filePicker i{font-size: 18px;} 
        #fileList li{float: left;position: relative;width: 28%;margin-left: 4%; margin-top: 10px;}
        #fileList li img{width: 100%;height: 80px;}
        #fileList li .cancel{position: absolute;color: white;border-radius: 50%;top: -10px;background-color: #5a5a5a;right: -10px;font-size: 18px;width: 22px;height: 22px;text-align: center;}
    </style>
</head>

<body>
    <div class="comment">
        <div id="filePicker"><i class="iconfont" style="color:#f55;font-size: 18px;">&#xe607;</i>  添加图片</div>
        <input id=file type="file" />   
        <ul id="fileList"></ul>
    </div>
</body>
<script src="http://www.zeptojs.cn/zepto.min.js"></script>
<script type="text/javascript">

$(function(){

    //压缩后图片数组
    var files=new Array();
    //用于压缩图片的canvas
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext('2d');
    //瓦片canvas
    var tCanvas = document.createElement("canvas");
    var tctx = tCanvas.getContext("2d");

    $("#file").change(function(){
        //图片是否符合规则
        if(test(this.value) == false || this.files[0].size/1024>1024*5) {
            $(".toast").text(test(this.value)?"图片过大,请选择小于5M的图片":"请选择图片文件").show();
            setTimeout(function(){$(".toast").hide();},2000);
            $('#file').val('');
            return;
        }
        //图片浏览
        if($("#fileList li img[alt='"+this.files[0].name+"']").length ==0){
            var url = getObjectURL(this.files[0]);
            var $li = $("<li><img src='"+url+"' alt='"+this.files[0].name+"'><div class='cancel'>x</div></li>");
            $("#fileList").append($li);
            var $cancel = $li.find(".cancel");
            $cancel.click(function(){
                var index = $(this).parent().index();
                if(index ==0)
                    files = files.slice(1);
                else if(index == files.length-1)
                    files = files.slice(0,index);
                else 
                    files = files.slice(0,index).concat(files.slice(index-files.length+1));                 
                $(this).parent().remove();
                event.stopPropagation();
            });

            $li.click(function(){
                $(".comment").hide();
                $(".single").show();
                $(".single img").attr("src",$(this).find("img").attr("src"));
                push();
            });

            compressImg(url,800,480);
            $('#file').val('');
        }
    })

    function test(value) {
        var regexp = new RegExp("(.JPEG|.jpeg|.JPG|.jpg|.PNG|.png)$",'g');
        return regexp.test(value);
    }

    function compressImg(url,maxWidth,maxHeight) {
        var canvas =  document.getElementById("canvas");
        var img = new Image();

        // 记住必须先绑定事件,才能设置src属性,否则img没内容可以画到canvas
        img.src = url;

        img.onload = function() {
            if(img.width > maxWidth){
                img.height *= maxWidth / img.width;
                img.width = maxWidth;
            }
            else{
                img.width *= parseFloat(maxHeight) / img.height;
                img.height = maxHeight;
            }
            //压缩后的图片流存到数组中
            files[files.length] = compress(img);
            //图片的base64字符流
            alert("图片的base64字节流:"+files[files.length-1]);
        };
    }

    //使用canvas对大图片进行压缩
    function compress(img) {
        var width = img.width;
        var height = img.height;
        //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
        var ratio;
        if ((ratio = width * height / 4000000) > 1) {
            ratio = Math.sqrt(ratio);
            width /= ratio;
            height /= ratio;
        } else {
            ratio = 1;
        }
        canvas.width = width;
        canvas.height = height;
        //铺底色
        ctx.fillStyle = "#fff";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        //如果图片像素大于100万则使用瓦片绘制
        var count;
        if ((count = width * height / 1000000) > 1) {
            count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
            //计算每块瓦片的宽和高
            var nw = ~~(width / count);
            var nh = ~~(height / count);
            tCanvas.width = nw;
            tCanvas.height = nh;
            for (var i = 0; i < count; i++) {
                for (var j = 0; j < count; j++) {
                    tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw* ratio, nh * ratio, 0, 0, nw, nh);
                    ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
                }
            }
        } else {
            ctx.drawImage(img, 0, 0, width, height);
        }
        //进行最小压缩
        var ndata = canvas.toDataURL('image/jpeg', 0.5);
        tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
        //获取文件base64字节流
        return ndata.split(",")[1];
    }

    //建立一個可存取到改file的url(读取url加载图片速度快于读取base64,图片越大字符流越长,小图片也得成百上千个字符)
    function getObjectURL(file) {
        var url = null;
        if (window.createObjectURL != undefined) { // basic
            url = window.createObjectURL(file);
        } else if (window.URL != undefined) { // mozilla(firefox)
            url = window.URL.createObjectURL(file);
        } else if (window.webkitURL != undefined) { // webkit or chrome
            url = window.webkitURL.createObjectURL(file);
        }
        return url;
    }

})
</script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值