• html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器


    以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一般的上传没有问题,不过如果是上传图片,且需要预览的话,就力有不逮了,趁着闲暇时间,给上传组件添加了单独的图片上传UI,支持图片预览和缩放(通过调整图片的大小以实现图片压缩)。

    v1.4版本已支持秒传+分片上传+断点续传(IE10+、其它标准浏览器),具体请参考Github代码

    上传组件特点

    1. 轻量级,不依赖任何JS库,核心代码(Q.Uploader.js)仅约700行,min版本加起来不到12KB
    2. 纯JS代码,无需Flash,无需更改后台代码即可实现带进度条(IE10+、其它标准浏览器)的上传,其它(eg:IE6+)自动降级为传统方式上传
    3. 单独的图片上传UI,支持图片预览(IE6+、其它浏览器)和缩放(IE10+、其它浏览器)
    4. 上传核心与UI界面分离,可以很方便的定制上传界面包括上传按钮
    5. 上传文件的同时可以指定上传参数,支持上传类型过滤
    6. 完善的事件回调,可针对上传的每个过程进行单独处理
    7. 方便的UI接口,上传界面可以随心所欲的定制

    效果如上图。由于浏览器不同,压缩效果各有不同,一个1.1MB、分辨率为 1920x1200 的图片,分辨率缩放为 1024x640 ,IE11上传后为199KB,Chrome45上传后为277KB,Firefox41上传后为360KB。

    使用代码

    html代码,导入样式及js上传组件,定义上传按钮及视图:

    <link href="../css/uploader-image.css" rel="stylesheet" type="text/css" />
    
    <div>
        <a id="upload-target" class="x-button">添加图片并上传</a>
    </div>
    <div id="upload-view"></div>
    
    <script type="text/javascript" src="../Q.Uploader.image.all.js"></script>

    js组件调用:

    var uploader = new Q.Uploader({
        url: "api/upload.ashx",
        target: document.getElementById("upload-target"),
        view: document.getElementById("upload-view"),
        //auto: false,
    
        //图片缩放
        scale: {
            //要缩放的图片格式
            types: ".jpg",
            //最大图片大小(width|height)
            maxWidth: 1024
        }
    });
    
    //uploader.start();

    一般无需更改后台代码,但如果使用了图片缩放(压缩),Firefox、Chrome 较早的版本上传后,后台可能会获取不到文件名,需要略微处理一下。以asp.net为例:

    HttpRequest request = context.Request;
    
    int c = request.Files.Count;
    
    //接收上传的数据并保存到服务器
    for (int i = 0; i < c; i++)
    {
        HttpPostedFile file = request.Files[i];
        
        //为兼容一些较早的浏览器,此处优先使用上传组件传递的文件名
        string fileName = request["fileName"];
        if (string.IsNullOrEmpty(fileName)) fileName = System.IO.Path.GetFileName(file.FileName);
    
        string path = context.Server.MapPath("~/upload/" + fileName);
        file.SaveAs(path);
    }

    关于上传

    参见  打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器

    关于预览

    IE10+等浏览器使用html5 api,其它浏览器使用滤镜预览。需要注意的是,IE8+由于安全性考虑,会获取不到文件真实地址,需要特殊处理一下。

    //生成图片预览地址(html5)
    function readAsURL(file, callback) {
        var URL = window.URL || window.webkitURL;
        if (URL) return callback(URL.createObjectURL(file));
    
        if (window.FileReader) {
            var fr = new FileReader();
            fr.onload = function (e) {
                callback(e.target.result);
            };
            fr.readAsDataURL(file);
        } else if (file.readAsDataURL) {
            callback(file.readAsDataURL());
        }
    }
    
    //图片预览
    function previewImage(box, task, callback) {
        var input = task.input,
            file = task.file || (input.files ? input.files[0] : undefined);
    
        if (file) {
            //IE10+、Webkit、Firefox etc
            readAsURL(file, function (src) {
                if (src) box.innerHTML = '<img src="' + src + '" />';
    
                callback && callback(src);
            });
        } else if (input) {
            var src = input.value;
    
            if (!src || /^w:\fakepath/.test(src)) {
                input.select();
                //解决ie报拒绝访问的问题
                parent.document.body.focus();
                //获取图片真实地址
                if (document.selection) src = document.selection.createRange().text;
            }
    
            if (src) {
                box.innerHTML = '<img src="' + src + '" />';
    
                try {
                    if (browser_ie > 6) box.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='" + src + "')";
                } catch (e) { }
            }
    
            callback && callback(src);
        }
    }

    关于缩放(压缩)

    原理是先通过canvas调整图片大小,生成base64数据,然后再通过html5 api (Blob) 转换为二进制对象上传。

    //将dataURL转为Blob对象,以用于ajax上传
    function dataURLtoBlob(base64, mimetype) {
        var ds = base64.split(','),
            data = atob(ds[1]),
    
            arr = [];
    
        for (var i = 0, len = data.length; i < len; i++) {
            arr[i] = data.charCodeAt(i);
        }
    
        if (Blob) return new Blob([new Uint8Array(arr)], { type: mimetype });
    
        var builder = new BlobBuilder();
        builder.append(arr);
        return builder.getBlob(mimetype);
    }
    
    //图片缩放
    function scaleImage(src, mimetype, ops, callback) {
        var image = new Image();
        image.src = src;
    
        image.onload = function () {
            var width = image.width,
                height = image.height,
    
                maxWidth = ops.maxWidth,
                maxHeight = ops.maxHeight,
    
                hasWidthScale = maxWidth && width > maxWidth,
                hasHeightScale = maxHeight && height > maxHeight,
    
                hasScale = hasWidthScale || hasHeightScale;
    
            //无需压缩
            if (!hasScale) return callback && callback(false);
    
            //根据宽度缩放
            if (hasWidthScale) {
                width = maxWidth;
                height = Math.floor(image.height * width / image.width);
            }
    
            //根据高度缩放
            if (hasHeightScale) {
                height = maxHeight;
                width = Math.floor(image.width * height / image.height);
            }
    
            var canvas = document.createElement("canvas"),
                ctx = canvas.getContext("2d");
    
            canvas.width = width;
            canvas.height = height;
    
            ctx.drawImage(image, 0, 0, width, height);
    
            callback && callback(canvas.toDataURL(mimetype), mimetype);
        };
    }

    其它参见源码及示例代码。

    代码下载

    asp.net 或其它后台示例代码

    源码更新请关注Github

    写在最后

    如果本文或本项目对您有帮助的话,请不吝点个赞。欢迎交流!

  • 相关阅读:
    使用react hook做一个小型完整项目(包括二级路由,动态路由,redux,tab切换,列表跳详情,登录, 守卫)
    项目实战【vue,react,微信小程序】(1705E)
    Vue(1706E)
    加入购物车动画(css)
    React从入门到精通(1704B)
    React(1702H)文章管理-cms系统
    React(1702H)文件上传和分页查找
    React (1702H) 点击复制、滚动条、图形验证码、ridis、密码rsa加密、token、发邮件、文件上传、sql语句
    位图算法
    def跨域+jwt
  • 原文地址:https://www.cnblogs.com/devin87/p/web-uploader-image.html
Copyright © 2020-2023  润新知