zoukankan      html  css  js  c++  java
  • HTML5 图片本地压缩上传插件

    ======================前端代码=========================
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>localResizeIMG</title>
        <!--引入JQuery 用于异步上传图片-->
        <script type="text/javascript" src="dist/jquery-3.1.1.min.js"></script>
        <!--引入 lrz 插件 用于压缩图片-->
        <script type="text/javascript" src="dist/lrz.bundle.js"></script>
    </head>
    <body>
    <input type="file" accept="image/jpeg" capture="camera">
    </body>
    <script>
        $("input[type=file]").change(function () {
            /* 压缩图片 */
            lrz(this.files[0], {
                 300 //设置压缩参数
            }).then(function (rst) {
                /* 处理成功后执行 */
                rst.formData.append('base64img', rst.base64); // 添加额外参数
                $.ajax({
                    url: "upload.php",
                    type: "POST",
                    data: rst.formData,
                    processData: false,
                    contentType: false,
                    success: function (data) {
                        $("<img />").attr("src", data).appendTo("body");
                    }
                });
            }).catch(function (err) {
                /* 处理失败后执行 */
            }).always(function () {
                /* 必然执行 */
            })
        })
    </script>
    </html>
    引入插件:<script type="text/javascript" src="dist/lrz.bundle.js"></script>
    
    绑定事件:$("input[type=file]").change(function () {/* 压缩上传处理 */});
    
    压缩图片:lrz(file, [options]);
    
      file 通过 input:file 得到的文件,或者直接传入图片路径
    
      [options] 这个参数允许忽略
    
        width {Number} 图片最大不超过的宽度,默认为原图宽度,高度不设定时会适应宽度
    
        height {Number} 图片的最大高度,默认为原图高度
    
        quality {Number} 图片压缩质量,取值 0 - 1,默认为 0.7
    
        fieldName {String} 后端接收的字段名,默认:file
    
    返回结果:promise 对象
    
      then(rst) 处理成功后执行
    
        rst.formData 后端可处理的数据
    
        rst.file 压缩后的file对象,如果压缩率太低,将会是原始file对象
    
        rst.fileLen 生成后的图片的大小,后端可以通过此值来校验是否传输完整
    
        rst.base64 生成后的图片base64,后端可以处理此字符串为图片,也可以直接用于 img.src = base64
    
        rst.base64Len 生成后的base64的大小,后端可以通过此值来校验是否传输完整
    
        rst.origin 也就是原始的file对象,里面存放了一些原始文件的信息,例如大小、日期等
    
    异步上传:processData 和 contentType 必须设为 false,否则服务端不会响应
    
    ======================后端代码=========================
    
    <?php
    $base64_image_content = $_POST['base64img'];
    $output_directory = './image'; //设置图片存放路径
    
    /* 检查并创建图片存放目录 */
    if (!file_exists($output_directory)) {
        mkdir($output_directory, 0777);
    }
    
    /* 根据base64编码获取图片类型 */
    if (preg_match('/^(data:s*image/(w+);base64,)/', $base64_image_content, $result)) {
        $image_type = $result[2]; //data:image/jpeg;base64,
        $output_file = $output_directory . '/' . md5(time()) . '.' . $image_type;
    }
    
    /* 将base64编码转换为图片编码写入文件 */
    $image_binary = base64_decode(str_replace($result[1], '', $base64_image_content));
    if (file_put_contents($output_file, $image_binary)) {
        echo $output_file; //写入成功输出图片路径
    }
    /*
     * LUploader图片压缩上传插件
     * 
     * 作者:黄磊
     * 
     * 报告漏洞,意见或建议, 请联系邮箱:xfhxbb@yeah.net
     * 
     * 创建于:2016年3月16日
     * 
     * Copyright 2016
     *
     * 获得使用本类库的许可, 您必须保留著作权声明信息。
     *
     */
    (function() {
        window.LUploader = function(el, params) {
            var _self = this;
            _self.trigger=el;
            _self.params = {
                accept: 'image/*',
                multiple: false,
                maxsize: 102400,
                imgObj: {},
                showsize: false,
                quality:0.1,
                url: ''
            }
            for (var param in params) {
                _self.params[param] = params[param];
            }
            _self.init();
        };
        LUploader.prototype.init = function() {
            var _self = this;
            _self.trigger.setAttribute('accept', _self.params.accept);
            _self.params.multiple && _self.trigger.setAttribute('multiple', '');
    
            var btn = document.querySelector('#' + _self.trigger.getAttribute('data-LUploader'));
            btn.addEventListener('click', function() {
                _self.trigger.click();
            });
            _self.trigger.addEventListener('change', function() {
                if (!this.files.length) return;
                var files = Array.prototype.slice.call(this.files);
                files.forEach(function(file, i) {
                    if (!//(?:jpeg|png|gif)/i.test(file.type)) return;
                    var reader = new FileReader();
                    _self.params.imgObj.size = file.size / 1024 > 1024 ? (~~(10 * file.size / 1024 / 1024)) / 10 + "MB" : ~~(file.size / 1024) + "KB";
                    var li = document.createElement("li");
                    li.innerHTML = '<div class="LUploader-progress"><span></span><input type="hidden" value="" /></div>';
                    if (_self.params.showsize) {
                        var div_size = document.createElement('div');
                        div_size.className = 'LUploader-size';
                        div_size.textContent = _self.params.imgObj.size;
                        li.appendChild(div_size);
                    }
                    var LUploaderList = _self.trigger.parentElement.querySelector('.LUploader-list');
                    if (!_self.params.multiple) { //假如是单个上传
                        if (_self.old_li) {
                            LUploaderList.removeChild(_self.old_li);
                        } else {
                            _self.old_li = li;
                        }
                    }
                    LUploaderList.appendChild(li);
                    LUploaderList.parentElement.nextElementSibling.style['display'] = 'none';
                    reader.onload = function() {
                        var params = dataSet(_self.trigger);
                        var url = _self.params.url;
                        var result = this.result;
                        var img = new Image();
                        _self.params.imgObj.src = img.src = result;
                        li.style['background-image'] = 'url(' + result + ')';
                        if (result.length <= _self.params.maxsize) {
                            img = null;
                            _self.upload(url, params, result, file.type, li);
                            return;
                        }
                        if (img.complete) {
                            callback();
                        } else {
                            img.onload = callback;
                        }
    
                        function callback() {
                            var data = _self.compress(img);
                            _self.upload(url, params, data, file.type, li);
                            img = null;
                        }
                    };
                    reader.readAsDataURL(file);
                });
            });
        };
        LUploader.prototype.compress = function(img) {
            var canvas = document.createElement("canvas");
            var ctx = canvas.getContext('2d');
            var moreCanvas = document.createElement("canvas");
            var morectx = moreCanvas.getContext("2d");
            var maxsize = 100 * 1024;
            var width = img.width;
            var height = img.height;
            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);
            var count;
            if ((count = width * height / 1000000) > 1) {
                count = ~~(Math.sqrt(count) + 1);
                var nw = ~~(width / count);
                var nh = ~~(height / count);
                moreCanvas.width = nw;
                moreCanvas.height = nh;
                for (var i = 0; i < count; i++) {
                    for (var j = 0; j < count; j++) {
                        morectx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);
                        ctx.drawImage(moreCanvas, i * nw, j * nh, nw, nh);
                    }
                }
            } else {
                ctx.drawImage(img, 0, 0, width, height);
            }
            var ndata = canvas.toDataURL('image/jpeg', this.params.quality);
            moreCanvas.width = moreCanvas.height = canvas.width = canvas.height = 0;
            return ndata;
        };
        LUploader.prototype.upload = function(url, obj, basestr, type, li) {
            var text = window.atob(basestr.split(",")[1]);
            var buffer = new Uint8Array(text.length);
            var pecent = 0;
            for (var i = 0; i < text.length; i++) {
                buffer[i] = text.charCodeAt(i);
            }
            var span = li.querySelector('.LUploader-progress').querySelector('span');
            var hidden_input = li.querySelector('.LUploader-progress').querySelector('input');
            var xhr = new XMLHttpRequest();
            xhr.open('post', url);
            xhr.onload = function(e) {
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
                    var data = JSON.parse(xhr.responseText);
                    var result = data['status'];
                    var text = result == 0 ? '上传成功' : '上传失败';
                    span.style['width'] = '100%';
                    span.innerHTML = text;
                    hidden_input.value = data['path'];
                }
                else {
                    span.innerHTML = '上传失败';
                }
            }
            xhr.upload.addEventListener('progress', function(e) {
                pecent = ~~(100 * e.loaded / e.total);
                span.style['width'] = pecent + '%';
                span.innerHTML = (pecent == 100 ? 99 : pecent) + '%';
            }, false);
            var data = {};
            for (var key in obj) {
                if (key !== 'luploader') {
                    if (obj[key] == 'basestr') {
                        data[key] = basestr;
                    } else {
                        data[key] = obj[key];
                    }
                }
            };
            data = serializeObject(data);
            xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.send(data);
        }
    
        function isArray(arr) {
            if (Object.prototype.toString.apply(arr) === '[object Array]') return true;
            else return false;
        };
    
        function serializeObject(obj) {
            if (typeof obj === 'string') return obj;
            var resultArray = [];
            var separator = '&';
            for (var prop in obj) {
                if (obj.hasOwnProperty(prop)) {
                    if (isArray(obj[prop])) {
                        var toPush = [];
                        for (var i = 0; i < obj[prop].length; i++) {
                            toPush.push(encodeURIComponent(prop) + '=' + encodeURIComponent(obj[prop][i]));
                        }
                        if (toPush.length > 0) resultArray.push(toPush.join(separator));
                    } else {
                        resultArray.push(encodeURIComponent(prop) + '=' + encodeURIComponent(obj[prop]));
                    }
                }
    
            }
            return resultArray.join(separator);
        };
    
        function dataSet(el) {
            var dataset = {};
            for (var i = 0; i < el.attributes.length; i++) {
                var attr = el.attributes[i];
                if (attr.name.indexOf('data-') >= 0) {
                    dataset[toCamelCase(attr.name.split('data-')[1])] = attr.value;
                }
            }
            return dataset;
        }
    
        function toCamelCase(string) {
            return string.toLowerCase().replace(/-(.)/g, function(match, group1) {
                return group1.toUpperCase();
            });
        };
    })();
    
    
    <!doctype html>
    <html>
    
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="Access-Control-Allow-Origin" content="*">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
        <meta content="yes" name="apple-mobile-web-app-capable">
        <meta content="black" name="apple-mobile-web-app-status-bar-style">
        <meta content="telephone=no" name="format-detection">
        <meta content="email=no" name="format-detection">
        <title>移动端图片压缩上传</title>
        <link rel="stylesheet" href="css/LUploader.css">
        <style>
        * {
            margin: 0;
            padding: 0;
        }
        h1{
        background-color: #19b5ee;
        color: #fff;
        font-size: 25px;
        text-align: center;
        padding: 10px;
        }
        li {
            list-style-type: none;
        }
        input {
            outline: none;
            -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
        }
        </style>
    </head>
    
    <body>
        <h1>LUploader移动端图片压缩上传</h1>
        <div class="LUploader" id="demo1">
            <div class="LUploader-container">
                <input data-LUploader='demo1' data-form-file='basestr' data-upload-type='front' type="file" />
                <ul class="LUploader-list"></ul>
            </div>
            <div>
                <div class="icon icon-camera font20"></div>
                <p>单击上传</p>
            </div>
        </div>
        <script src="js/LUploader.js?r=<?php echo  time();?>"></script>
        <script>
        [].slice.call(document.querySelectorAll('input[data-LUploader]')).forEach(function(el) {
            new LUploader(el, {
                url: './upload.php',//post请求地址
                multiple: false,//是否一次上传多个文件 默认false
                maxsize: 102400,//忽略压缩操作的文件体积上限 默认100kb
                accept: 'image/*',//可上传的图片类型
                quality: 0.5,//压缩比 默认0.1  范围0.1-1.0 越小压缩率越大
                showsize:true//是否显示原始文件大小 默认false
            });
        });
        </script>
    </body>
    
    </html>
  • 相关阅读:
    爱信诺面试总结
    项目进展日志6
    项目进展日志5
    项目进展日志4
    项目进展日志3
    项目进展日志2
    项目阶段总结
    项目进展日志
    事物的ACID特性
    5.27作业
  • 原文地址:https://www.cnblogs.com/lujiang/p/9443027.html
Copyright © 2011-2022 走看看