spring(java,js,html) 截图上传图片实例详解
程序员文章站
2024-03-12 22:47:26
html
<#-- 上传头像 测试页 使用imgareaselect 插件 -->
最后 上传了这个插件 共学习参考
html
<#-- 上传头像 测试页 使用imgareaselect 插件 -->
最后 上传了这个插件 共学习参考
<link rel="stylesheet" type="text/css" href="${frontres}/imgareaselect/css/imgareaselect-animated.css" /> <link rel="stylesheet" type="text/css" href="${frontres}/imgareaselect/css/index.css" /> <script type="text/javascript" src="${frontres}/imgareaselect/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="${frontres}/imgareaselect/jquery.imgareaselect.pack.js"></script> <script type="text/javascript" src="${frontres}/imgareaselect/ajaxfileupload.js"></script> <script> function addfile(obj){ //document.getelementbyid('img').src = path; $.ajaxfileupload({ url:'${huluurl}/trainer/upload/ajaxupload', //用于文件上传的服务器端请求地址 secureuri: false, //是否需要安全协议,一般设置为false fileelementid: 'photofile', //文件上传域的id datatype: 'json', //返回值类型 一般设置为json success: function (data){//服务器成功响应处理函数 var infoarray = eval("("+data+")"); //包数据解析为json格式 var arr = infoarray.data; $("#img").attr("src","/images/"+arr.photo); }, error: function (){//服务器响应失败处理函数 alert('与服务器通信失败,请稍后再试!'); parent.location.reload(); } }); } function preview(img, selection) { if (!selection.width || !selection.height) return; //预览 var scalex = 100 / selection.width; var scaley = 100 / selection.height; //var imgx = document.getelementbyid("photo").style.width; var imgx = parseint($("#photo").css("width").split("px")[0]); var imgy = parseint($("#photo").css("height").split("px")[0]); console.debug(imgx+"===="+imgy); $('#preview img').css({ width : math.round(scalex * imgx), height : math.round(scaley * imgy), marginleft : -math.round(scalex * selection.x1), margintop : -math.round(scaley * selection.y1) }); $('#x1').val(selection.x1); $('#y1').val(selection.y1); $('#x2').val(selection.x2); $('#y2').val(selection.y2); $('#w').val(selection.width); $('#h').val(selection.height); //后台数据 $('#x1s').val(selection.x1); $('#y1s').val(selection.y1); $('#x2s').val(selection.x2); $('#y2s').val(selection.y2); $('#imgx').val(parseint(imgx));//原图width宽度 $('#imgy').val(parseint(imgy));//原图高度height } $(function(selection) { var imgx = $("#photo").css("width").split("px")[0]; var imgy = $("#photo").css("height").split("px")[0]; var ares = 0; console.debug(imgx+"===="+imgy); if(imgx>imgy){ ares = imgy; }else{ ares = imgx; } var ias = $('#photo').imgareaselect({ aspectratio : '1:1', handles : true, fadespeed : 200, onselectchange : preview, instance : true }); ias.setselection(0, 0, ares-1, ares-1);//初始化选择区域 ias.setoptions({ show : true }); ias.update(); $(".imgareaselect-outer").css("cursor","crosshair"); $(".imgareaselect-outer").css("background-color","rgba(255,255,255,0.9)"); //预览 var scalex = 100 / ares; var scaley = 100 / ares; $('#preview img').css({ width : math.round(scalex * imgx), height : math.round(scaley * imgy), marginleft : -math.round(scalex * 0), margintop : -math.round(scaley * 0) }); //后台数据 $('#x1s').val(0); $('#y1s').val(0); $('#x2s').val(ares-1); $('#y2s').val(ares-1); $('#imgx').val(imgx);//原图width宽度 $('#imgy').val(imgy);//原图高度height }); </script> <div class="container" style="margin-top:20px;"> <div class="row"> <div class="col-xs-9 pull-right"> <div class="media media-heading"> <h4 style="font-weight: 600;float: left">上传照片</h4> </div> <div class="row" style="margin-top: 15px"> <div class="col-lg-12"> <div class="btn-group" style="float: left"> <div class="btn btn-default" role="button" style="position: relative; overflow: hidden;background-color: #8dc21f;color: #ffffff;"> <span>+添加照片</span> <input id="photofile" type="file" name="photofile" onchange="addfile(this);" style="height:34px;position: absolute; right: 0px; top: 0px; margin: 0px; padding: 0px; cursor: pointer; opacity: 0;"> </div> </div> <span style="float: left; margin-left: 15px; color: #888888"> <ul> <li>建议本人照片</li> <li>只支持jpg、png、gif,大小不超过5m</li> </ul> </span> </div> </div> <div class="row"> <div class="col-lg-12"> <div class="shangchuantouxiang"> <img src="/images/${(trainer.photo)!""}" alt="..." id ="img" class="img-circle" style="width: 320px; height: 320px"> </div> </div> </div> <form action ="${huluurl}/trainer/upload/uploadphototest" method="post" enctype="multipart/form-data" > <input type="text" id="x1s" name = "x1s" value="-" /> <input type="text" id="y1s" name = "y1s" value="-" /> <input type="text" id="x2s" name = "x2s" value="-" /> <input type="text" id="y2s" name = "y2s" value="-" /> <input type="text" id="imgx" name = "imgx" value="-" /> <input type="text" id="imgy" name = "imgy" value="-" /> <div class="row" style="margin-top: 15px; margin-left: 80px"> <div class="col-lg-5"> <div class="btn-group"> <button type="button" class="btn btn-default"id="chongxinshangchuan">重新上传</button> </div> <div class="btn-group"> <button type="submit" class="btn btn-default" id="baocun"> 保存 </button> </div> </div> </div> </form> </div> </div> </div> <div id="root"> <div id="main"> <div class="container demo"> <div style="float: left; width: 50%;"> <p class="instructions">click and drag on the image to select an area.</p> <div style="width: 302px;height: 302px;"> <div style="width: 302px;height:302px;border: 1px solid #aaa;"> <div style="line-height: 300px; text-align: center; overflow: hidden; z-index: 1001; width: 300px; height: 300px; position: relative; left: 50%; top: 50%; margin-left: -150px; margin-top: -150px; "> <img id="photo" src="/images/${(trainer.photo)!""}" style="max-height:300px;max-width: 300px;" /> </div> </div> </div> </div> <div style="float: left; width: 50%;"> <p style="font-size: 110%; font-weight: bold; padding-left: 0.1em;">selection preview</p> <div style="width: 100px; height: 100px;"> <div id="preview" style="width: 100px; height: 100px; overflow: hidden;"> <img src="/images/${trainer.photo!}" style="width: 100px; height: 100px;" /> </div> </div> <table> <thead> <tr> <th colspan="2" style="font-size: 110%; font-weight: bold; text-align: left; padding-left: 0.1em;">coordinates</th> <th colspan="2" style="font-size: 110%; font-weight: bold; text-align: left; padding-left: 0.1em;">dimensions</th> </tr> </thead> <tbody> <tr> <td style="width: 10%;"><b>x<sub>1</sub>:</b></td> <td style="width: 30%;"><input type="text" id="x1" value="-" /></td> <td style="width: 20%;"><b>width:</b></td> <td><input type="text" value="-" id="w" /></td> </tr> <tr> <td><b>y<sub>1</sub>:</b></td> <td><input type="text" id="y1" value="-" /></td> <td><b>height:</b></td> <td><input type="text" id="h" value="-" /></td> </tr> <tr> <td><b>x<sub>2</sub>:</b></td> <td><input type="text" id="x2" value="-" /></td> <td></td> <td></td> </tr> <tr> <td><b>y<sub>2</sub>:</b></td> <td><input type="text" id="y2" value="-" /></td> <td></td> <td></td> </tr> </tbody> </table> </div> </div> </div> </div>
java
//显示图片需要在服务端配置一个虚拟路径 (tomcat) server.xml <context debug="0" docbase="g:\image" path="/images" reloadable="true"/> 回显一下数据 [java] view plain copy 在code上查看代码片派生到我的代码片 /** * 跳到上传头像2(可截取图片) * * @return */ @requestmapping(value = "touploadphoto", method = requestmethod.get) public modelandview touploadtest() { modelandview mav = leftmenu("/trainer/upload/uploadphoto"); // trainer trainer = null; try { long userid = frontshiroutil.getuserid(); if (null != userid) { trainer = trainerrepo.findone(userid); trainerdbsvc.updatelastlogintime(userid); } } catch (exception e) { e.printstacktrace(); } mav.addobject("trainer", trainer); return mav; } // 局部刷新上传图片 @requestmapping("/ajaxupload") public @responsebody ajaxresult ajaxupload(multiparthttpservletrequest request) { trainer trainer = new trainer(); // 获得第1张图片(根据前台的name名称得到上传的文件) multipartfile file = request.getfile("photofile"); if (file.getsize() != 0) { // 获得文件名: string filename = file.getoriginalfilename(); string timetype = null; if (null != filename && !filename.equals("")) { string imgtype = filename.substring(filename.lastindexof(".")); // 获取路径 string ctxpath = "e:/rudongimage/photo/"; // 创建文件 file dirpath = new file(ctxpath); if (!dirpath.exists()) { dirpath.mkdirs(); } // 以时间为文件名 date date = new date(); simpledateformat sdformat = new simpledateformat("yyyymmddhhmmss");// 24小时制 string lgtime = sdformat.format(date); timetype = lgtime + imgtype; file uploadfile = new file(ctxpath + timetype); try { filecopyutils.copy(file.getbytes(), uploadfile); } catch (ioexception e) { e.printstacktrace(); } } string headphotopath = "photo/" + timetype; trainer.setphoto(headphotopath); } try { // 根据userid查询培训师 long userid = frontshiroutil.getuserid(); if (null != userid) { trainer.setuserid(userid); // 更新培训师头像 trainerdbsvc.updatetrainerphoto(trainer); } } catch (exception e) { e.printstacktrace(); } return ajaxresult.createsuccess(trainer);//<span style="font-family: arial, helvetica, sans-serif;">ajaxresult 可修改</span> } /** * 截取区域上传图片测试 * * @return */ @requestmapping(value = "uploadphototest", method = requestmethod.post) public modelandview uploadphototest(multiparthttpservletrequest request, @requestparam("x1s") integer x1, @requestparam("y1s") integer y1, @requestparam("x2s") integer x2, @requestparam("y2s") integer y2, @requestparam("imgx") integer imgwidth, @requestparam("imgy") integer imgheight) { modelandview mav = leftmenu("redirect:/trainer/upload/touploadphoto"); trainer trainer = null; try { // 根据userid查询培训师 long userid = frontshiroutil.getuserid(); if (null != userid) { trainer = trainerrepo.findone(userid); } } catch (exception e) { e.printstacktrace(); } file uploadfile = new file("e:/rudongimage/" + trainer.getphoto()); inputstream is = null; bufferedimage src = null; int w = -1; int h = -1; try { is = new fileinputstream(uploadfile); src = javax.imageio.imageio.read(is); w = src.getwidth(null); // 得到源图宽 h = src.getheight(null); // 得到源图高 is.close(); } catch (exception e) { e.printstacktrace(); } integer l = 0; // 以小边为准(原图尺寸) if (w < h) { l = w; } else { l = h; } // 以小边为准(缩略图尺寸) integer l2 = 0; if (imgwidth < imgheight) { l2 = imgwidth; } else { l2 = imgheight; } integer x = (x1 * l) / l2;// 起点x integer y = (y1 * l) / l2;// 起点y integer xs = (x2 * l) / l2;// 终点x 对角线位置 integer ys = (y2 * l) / l2;// 终点y 对角线位置 imageutil imageutil = new imageutil(); // 返回截取后的文件名 string photoname = ""; imageutil.cutimage(uploadfile, "e:/rudongimage/photo/", x, y, xs - x, ys - y); string headphotopath = "photo/" + photoname; trainer.setphoto(headphotopath); // 更新培训师头像 trainerdbsvc.updatetrainerphoto(trainer); return mav; }
工具类
import java.awt.color; import java.awt.graphics; import java.awt.image; import java.awt.rectangle; import java.awt.image.bufferedimage; import java.io.file; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.ioexception; import java.io.inputstream; import java.io.outputstream; import java.util.arrays; import java.util.iterator; import javax.imageio.imageio; import javax.imageio.imagereadparam; import javax.imageio.imagereader; import javax.imageio.stream.imageinputstream; import org.slf4j.logger; import org.slf4j.loggerfactory; /** * 图片截取工具类 */ public class imageutil { private logger log = loggerfactory.getlogger(getclass()); private static string default_thumb_prevfix = "thumb_"; private static string default_cut_prevfix = "cut_"; private static boolean default_force = false; /** * <p>title: cutimage</p> * <p>description: 根据原图与裁切size截取局部图片</p> * @param srcimg 源图片 * @param output 图片输出流 * @param rect 需要截取部分的坐标和大小 */ public void cutimage(file srcimg, outputstream output, java.awt.rectangle rect){ if(srcimg.exists()){ java.io.fileinputstream fis = null; imageinputstream iis = null; try { fis = new fileinputstream(srcimg); // imageio 支持的图片类型 : [bmp, bmp, jpg, jpg, wbmp, jpeg, png, png, jpeg, wbmp, gif, gif] string types = arrays.tostring(imageio.getreaderformatnames()).replace("]", ","); string suffix = null; // 获取图片后缀 if(srcimg.getname().indexof(".") > -1) { suffix = srcimg.getname().substring(srcimg.getname().lastindexof(".") + 1); }// 类型和图片后缀全部小写,然后判断后缀是否合法 if(suffix == null || types.tolowercase().indexof(suffix.tolowercase()+",") < 0){ log.info("sorry, the image suffix is illegal. the standard image suffix is {}." + types); return ; } // 将fileinputstream 转换为imageinputstream iis = imageio.createimageinputstream(fis); // 根据图片类型获取该种类型的imagereader imagereader reader = imageio.getimagereadersbysuffix(suffix).next(); reader.setinput(iis,true); imagereadparam param = reader.getdefaultreadparam(); param.setsourceregion(rect); bufferedimage bi = reader.read(0, param); imageio.write(bi, suffix, output); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } finally { try { if(fis != null) fis.close(); if(iis != null) iis.close(); if(output != null) output.close(); } catch (ioexception e) { e.printstacktrace(); } } }else { log.info("the src image is not exist."); } } public void cutimage(file srcimg, outputstream output, int x, int y, int width, int height){ cutimage(srcimg, output, new java.awt.rectangle(x, y, width, height)); } public void cutimage(file srcimg, string destimgpath, java.awt.rectangle rect){ file destimg = new file(destimgpath); if(destimg.exists()){ string p = destimg.getpath(); try { if(!destimg.isdirectory()) p = destimg.getparent(); if(!p.endswith(file.separator)) p = p + file.separator; cutimage(srcimg, new java.io.fileoutputstream(p + default_cut_prevfix + "_" + new java.util.date().gettime() + "_" + srcimg.getname()), rect); } catch (filenotfoundexception e) { log.info("the dest image is not exist."); } }else log.info("the dest image folder is not exist."); } public void cutimage(file srcimg, string destimg, int x, int y, int width, int height){ cutimage(srcimg, destimg, new java.awt.rectangle(x, y, width, height)); } public void cutimage(string srcimg, string destimg, int x, int y, int width, int height){ cutimage(new file(srcimg), destimg, new java.awt.rectangle(x, y, width, height)); } /** * <p>title: thumbnailimage</p> * <p>description: 根据图片路径生成缩略图 </p> * @param imagepath 原图片路径 * @param w 缩略图宽 * @param h 缩略图高 * @param prevfix 生成缩略图的前缀 * @param force 是否强制按照宽高生成缩略图(如果为false,则生成最佳比例缩略图) */ public void thumbnailimage(file srcimg, outputstream output, int w, int h, string prevfix, boolean force){ if(srcimg.exists()){ try { // imageio 支持的图片类型 : [bmp, bmp, jpg, jpg, wbmp, jpeg, png, png, jpeg, wbmp, gif, gif] string types = arrays.tostring(imageio.getreaderformatnames()).replace("]", ","); string suffix = null; // 获取图片后缀 if(srcimg.getname().indexof(".") > -1) { suffix = srcimg.getname().substring(srcimg.getname().lastindexof(".") + 1); }// 类型和图片后缀全部小写,然后判断后缀是否合法 if(suffix == null || types.tolowercase().indexof(suffix.tolowercase()+",") < 0){ log.info("sorry, the image suffix is illegal. the standard image suffix is {}." + types); return ; } log.info("target image's size, width:{}, height:{}.",w,h); image img = imageio.read(srcimg); // 根据原图与要求的缩略图比例,找到最合适的缩略图比例 if(!force){ int width = img.getwidth(null); int height = img.getheight(null); if((width*1.0)/w < (height*1.0)/h){ if(width > w){ h = integer.parseint(new java.text.decimalformat("0").format(height * w/(width*1.0))); log.info("change image's height, width:{}, height:{}.",w,h); } } else { if(height > h){ w = integer.parseint(new java.text.decimalformat("0").format(width * h/(height*1.0))); log.info("change image's width, width:{}, height:{}.",w,h); } } } bufferedimage bi = new bufferedimage(w, h, bufferedimage.type_int_rgb); graphics g = bi.getgraphics(); g.drawimage(img, 0, 0, w, h, color.light_gray, null); g.dispose(); // 将图片保存在原目录并加上前缀 imageio.write(bi, suffix, output); output.close(); } catch (ioexception e) { system.out.println("generate thumbnail image failed."+e); } }else{ system.out.println("the src image is not exist."); } } public void thumbnailimage(file srcimg, int w, int h, string prevfix, boolean force){ string p = srcimg.getabsolutepath(); try { if(!srcimg.isdirectory()) p = srcimg.getparent(); if(!p.endswith(file.separator)) p = p + file.separator; thumbnailimage(srcimg, new java.io.fileoutputstream(p + prevfix +srcimg.getname()), w, h, prevfix, force); } catch (filenotfoundexception e) { log.info("the dest image is not exist."+e); } } public void thumbnailimage(string imagepath, int w, int h, string prevfix, boolean force){ file srcimg = new file(imagepath); thumbnailimage(srcimg, w, h, prevfix, force); } public void thumbnailimage(string imagepath, int w, int h, boolean force){ thumbnailimage(imagepath, w, h, default_thumb_prevfix, default_force); } public void thumbnailimage(string imagepath, int w, int h){ thumbnailimage(imagepath, w, h, default_force); } public void readusingimagereader(string src, string dest, int w, int h)throws exception { // 取得图片读入器 iterator readers = imageio.getimagereadersbyformatname("png"); imagereader reader = (imagereader) readers.next(); // 取得图片读入流 inputstream source = new fileinputstream(src); imageinputstream iis = imageio.createimageinputstream(source); reader.setinput(iis, true); // 图片参数 imagereadparam param = reader.getdefaultreadparam(); // 100,200是左上起始位置,300就是取宽度为300的,就是从100开始取300宽,就是横向100~400,同理纵向200~350的区域就取高度150 // rectangle rect = new rectangle(100, 200, 300, 150);// int hh = 0; if (h > 100) hh = (h - 100) / 3; rectangle rect = new rectangle(0, hh, 227, 100); param.setsourceregion(rect); bufferedimage bi = reader.read(0, param); imageio.write(bi,"jpg", new file(dest)); } public static void main(string[] args) throws exception { //new imageutil().thumbnailimage("imgs/tulips.jpg", 150, 100); //new imageutil().cutimage("imgs/tulips.jpg","imgs", 250, 70, 300, 400); //new imageutil().readusingimagereader("e://rudongimage/photo/20160302090226.png", "e://rudongimage/photo/2.png", 227, 163); } }
xml配置
<bean id="multipartresolver" class="org.springframework.web.multipart.commons.commonsmultipartresolver"> <!-- one of the properties available; the maximum file size in bytes <property name="maxuploadsize" value="9999999999"/> --> </bean>
插件连接
样式没调 有点丑功能都有。