1. 程式人生 > >使用canvas上傳圖片+上傳進度

使用canvas上傳圖片+上傳進度

實現效果:

速度過快,調式瀏覽器方式:F12

 

後臺java程式碼

public String imageshangchuan(@RequestPart("xxx") MultipartFile multipartFile, Model model, HttpServletRequest request) {

        if (!multipartFile.getContentType().contains("image/")) {
            model.addAttribute("err", "只能是圖片檔案!");
            
return "/inputfile"; } if (multipartFile.getSize() > 1024 * 1024 * 5) { model.addAttribute("err", "只能是5M以下!"); return "/inputfile"; } //取得相對路徑 String basePath = request.getServletContext().getRealPath("/img"); File files = new File(basePath);
if(!files.exists()){ files.mkdir(); } String rekativePath; try { rekativePath = makeImagePath(basePath, multipartFile.getOriginalFilename()); File file = new File(rekativePath); file.getParentFile().mkdir(); multipartFile.transferTo(file); }
catch (IOException e) { model.addAttribute("err", "上傳失敗,請重試"); return "/inputfile"; } return "/index"; } public String makeImagePath (String basePath, String fileName){ Date date = new Date(); //String[] filename = simpleFile(fileName); return String.format("%s%s%s%supload_%s_%s.%s", basePath, File.separator, new SimpleDateFormat("yyyyMMdd").format(date), File.separator, "11", new SimpleDateFormat("hhmmss").format(date), "jpg" ); } public String[] simpleFile (String file){ int sum = file.lastIndexOf("."); return new String[]{ file.substring(0, sum), file.substring(sum + 1) }; }
View Code

方法一:canvas實現

<html>
<head>
    <title>Title</title>
</head>
<body>
<input type="file" id="myfile"/>
<canvas id="myCanvas" width="200" height="250" style="border:1px solid #d3d3d3;">

</canvas>
<button onclick="test()">提交</button>
<script src="css/jquery-1.11.3.js"></script>
<script>
    //選擇圖片後
    myfile.onchange=function () {
        createURLImg(myfile.files[0]);
    }
    var pen=myCanvas.getContext("2d");
    //載入入canvas
    function createURLImg(file,callback) {
        var imgUrl=URL.createObjectURL(file);
        var image=new Image();
        image.src=imgUrl;
        image.onload=function (ev) {
            pen.drawImage(image,0,0,200,250);
            if(callback) callback();
            URL.revokeObjectURL(imgUrl);
        }
    }
    //提交按鈕
    function test() {
        myCanvas.toBlob(function (result) {
            var form=new FormData();
            form.append("xxx",result);
            ajax(form);
        })
    }
    
    function biafenb(r) {
        if(!pen) pen=myCanvas.getContext("2d");
        pen.save();
        pen.globalAlpha=0.3;
        pen.fillRect(0,(1-r)*200,200,250);
        pen.globalAlpha=1;
        pen.fillStyle = "white";
        pen.font = "20px 微軟雅黑";
        pen.textAlign='center';
        pen.fillText(Math.round(r*100)+"%",100,100);
        pen.restore();
    }

    function ajax(formData) {
        $.ajax({
            url:"/bbbbb",
            type:"post",
            Accept:"html/text;chatset=utf-8",
            contentType:false,
            data:formData,
            processData:false,
            xhr: function () {
                var myXhr = $.ajaxSettings.xhr();
                myXhr.upload.onprogress=function (ev) {
                    pen.clearRect(0,0,200,250);
                    createURLImg(myfile.files[0],function () {
                        biafenb(ev.loaded/ev.total);
                    })
                }
                return myXhr;
            }, success: function (data) {
                console.log("上傳成功!!!!");
            }, error: function () {
                console.log("上傳失敗!");
            }
        })
    }
</script>
</body>
</html>
View Code

方法二:img+canvas實現

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>canvas + ajax</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"
          integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <style>
        #myimg {
            border: 3px solid gray;
            border-radius: 5px;
            position: absolute;
            top: 0;
            left: 0;
        }
        #mymask {
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head>
<body>


<div class="container">
    <div style="margin-top: 2em;">
        <input type="file" id="myfile" style="display: none"> <!-- 選擇檔案後,要預覽 -->
        <button class="btn btn-primary" onclick="myfile.click()">選擇圖片</button>
        <button class="btn btn-primary" onclick="clickMe()">上傳圖片</button>
    </div>

    <div style="position: relative">
        <img src="" id="myimg" title="暫時沒有上傳" width="200" height="200"/>
        <canvas id="mymask" width="200" height="200">不支援canvas</canvas>
    </div>
</div>


<script>

    var ctx;
    myfile.onchange = () => { // 預覽圖片
        var imgUrl = URL.createObjectURL(event.target.files[0]);
        myimg.src = imgUrl;
        myimg.onload = () => URL.revokeObjectURL(imgUrl);

    };

    function clickMe() {
        compressImgWithCanvas(myfile.files[0], uploadWithAJAX);
    }

    /**
     * 壓縮圖片,然後執行某些任務
     */
    function compressImgWithCanvas(blob, taskCallback) {
        var rat = 2;
        var w = myimg.naturalWidth / rat, h = myimg.naturalHeight / rat;

        var canvas = document.createElement("canvas");
        canvas.width = w;
        canvas.height = h;

        var ctx = canvas.getContext('2d');
        ctx.drawImage(myimg, 0, 0, w, h);
        ctx.fillText("nf147", w - 20, h - 20);

        canvas.toBlob(taskCallback, "image/jpeg");
    }

    /**
     * 更新預覽進度
     */
    function refreshProgress(r) {
        if (!ctx) ctx = mymask.getContext('2d');
        ctx.save();
        ctx.clearRect(0, 0, 200, 200);
        ctx.globalAlpha = 0.6;
        ctx.fillRect(0, (1 - r) * 200, 200, 200);
        ctx.globalAlpha = 1;
        ctx.fillStyle = "white";
        ctx.font = "20px 微軟雅黑";
        ctx.fillText(r * 100 + '%', 80, 180);
        ctx.restore();
    }

    /**
     * 通過 AJAX 上傳 blob 型別的檔案
     * @param blob
     */
    function uploadWithAJAX(blob) {
        var fd = new FormData();
        fd.append("xxx", blob);

        $.ajax({
            method: 'post',
            url: "/bbbbb",
            cache: false,
            contentType: false,
            data: fd,
            processData: false,
            xhr: () => {
            var xhr = $.ajaxSettings.xhr();
        xhr.upload.onprogress = (ev) => {
            refreshProgress(ev.loaded / ev.total);
        };
        return xhr;
    }
    }).done(console.log)
            .fail((xhr, staus, err) => console.error(xhr, staus, err));

    }

</script>


<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"
        integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"
        crossorigin="anonymous"></script>
</body>
</html>
View Code