使用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) }; }
方法一: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>
方法二: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>