html5 圖片上傳,支持圖片預覽、壓縮、及進度顯示,兼容IE6+及標準瀏覽器

原文: html5 圖片上傳,支持圖片預覽、壓縮、及進度顯示,兼容IE6+及標準瀏覽器

之前寫過上傳組件,見 打造 html5 文件上傳組件,實現進度顯示及拖拽上傳,兼容IE6+及其它標準瀏覽器,對付通常的上傳沒有問題,不過若是是上傳圖片,且須要預覽的話,就力有不逮了,趁着閒暇時間,給上傳組件添加了單獨的圖片上傳UI,支持圖片預覽和縮放(經過調整圖片的大小以實現圖片壓縮)。javascript

上傳組件特色

  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。css

使用代碼

html代碼,導入樣式及js上傳組件,定義上傳按鈕及視圖:html

<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組件調用:html5

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爲例:java

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+及其它標準瀏覽器git

關於預覽

IE10+等瀏覽器使用html5 api,其它瀏覽器使用濾鏡預覽。須要注意的是,IE8+因爲安全性考慮,會獲取不到文件真實地址,須要特殊處理一下。github

//生成圖片預覽地址(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) 轉換爲二進制對象上傳。web

//將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);
    };
}

 

其它參見源碼及示例代碼。ajax

代碼下載

asp.net 或其它後臺示例代碼canvas

源碼更新請關注Github

寫在最後

若是本文或本項目對您有幫助的話,請不吝點個贊。歡迎交流!

相關文章
相關標籤/搜索