链接:https://zhuanlan.zhihu.com/p/24465742
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者:梦游的龙猫(转载已获得作者许可)
很久没有更新博客了,再不写点东西都烂了。
这次更新一个小内容,是两个插件的组合使用,实现头像上传功能。
业务需求:
- 头像上传功能,要对上传的文件进行剪切,且保证头像到服务器时必须是正方形的。
- 优化的显示样式,基础的样式实在太难看了。
- 上传的头像需要进行质量压缩跟大小裁剪,以减缓浏览器的压力。
成果预览:
使用到的技术插件
-
Jcrop:用于前端“裁剪”图片
- bootstrap-fileinput:用于前端优化上传控件样式
- ARTtemplate:JS版的JSTL?反正就是一个腾讯的模板化插件,很好用,真心。
-
bootstrap-sco.modal.js:这个是bootstrap的一个模态插件
-
SpringMVC:使用框架自带的MultipartFile来获取文件(效率能够大大的提高)
- Image:这个是Java的内置类,用于处理图片很方便。
原理说明
首先是Jcrop这个前端JS插件,这个插件很好用,其实在各大网站中也很常见,先上图:说说原理,实际上,Jcrop并没有在客户端帮我们把图片进行裁剪,只是收集了用户的“裁剪信息”,然后传到后端,最后的裁剪和压缩,还是要依靠服务器上的代码来进行。
我们可以看到这个插件在图片上显示出了8个控制点,让用户选择裁剪区域,当用户选择成功后,会自动的返回“裁剪信息”,所谓的裁剪信息,其实就是选框的左上角原点坐标,及裁剪框的宽度和高度,通过这四个值,在后端就可以进行裁剪工作了。
但是我们要注意,用户在上传图片的时候,长度宽度都是不规则的,当然我们可以用bootstap-fileinput这个插件去限制用户只能上传指定宽高的图片,但这就失去了我们“裁剪”的意义,而且用户的体验就非常差劲。然而jcrop所返回的坐标值及宽高,并不是基于所上传图片自身的像素,而是如图中所示,是外层DIV的宽高。举一个例子,上图我实际放入的个人照片宽度是852px,但是Jcrop的截取宽度是312px,这个312px并不是真正图片上的实际宽度,是经过缩放后的宽度,所以我们后端一定需要重新对这个312px进行一次还原,还原到照片实际比例的宽度。
好啦,原理就是这样子。接下来,就是上代码了。
HTML
<script id="portraitUpload" type="text/html"> <div style="padding: 10px 20px"> <form role="form" enctype="multipart/form-data" method="post"> <div class="embed-responsive embed-responsive-16by9"> <div class="embed-responsive-item pre-scrollable"> <img alt="" src="${pageContext.request.contextPath}/img/showings.jpg" id="cut-img" class="img-responsive img-thumbnail"/> </div> </div> <div class="white-divider-md"></div> <input type="file" name="imgFile" id="fileUpload"/> <div class="white-divider-md"></div> <div id="alert" class="alert alert-danger hidden" role="alert"></div> <input type="hidden" id="x" name="x"/> <input type="hidden" id="y" name="y"/> <input type="hidden" id="w" name="w"/> <input type="hidden" id="h" name="h"/> </form> </div> script>
这个就是一个ArtTemplate的模板代码,就写在