cropper裁剪图片并上传

深碍√TFBOYSˉ_ 2022-05-17 09:48 390阅读 0赞

引入cropper所依赖的js和css,可在官网下载。

我的资源地址:https://download.csdn.net/download/rexueqingchun/10593965

把裁剪的图片转化为base64上传

前台程序

  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>上传图片</title>
  7. <link rel="stylesheet" href="css/bootstrap.min.css">
  8. <link rel="stylesheet" href="css/cropper.css">
  9. <link rel="stylesheet" href="css/main.css">
  10. <script src="js/jquery-1.11.3.js"></script>
  11. <script src="js/bootstrap.bundle.min.js"></script>
  12. <script src="js/cropper.js"></script>
  13. <script type="text/javascript">
  14. $(function () {
  15. var console = window.console || { log: function () {} };
  16. var URL = window.URL || window.webkitURL;
  17. var $image = $('#image');
  18. var $download = $('#download');
  19. var $dataX = $('#dataX');
  20. var $dataY = $('#dataY');
  21. var $dataHeight = $('#dataHeight');
  22. var $dataWidth = $('#dataWidth');
  23. var $dataRotate = $('#dataRotate');
  24. var $dataScaleX = $('#dataScaleX');
  25. var $dataScaleY = $('#dataScaleY');
  26. var options = {
  27. aspectRatio: 1 / 1, //裁剪框的宽高比
  28. viewMode: 1, //视图模式,默认为0:无限制,1:截取框不能移到图片外部,2:不全部铺满背景,3:全部铺满背景
  29. dragMode: 'move',//拖拽模式,默认为crop:产生一个新的裁剪框,可改变大小,move:可移动图片,none:不可移动图片
  30. preview: '.img-preview', //添加额外的元素(容器)以供预览
  31. autoCropArea: 0.5, //定义初始化裁剪框对比图片的比例大小,默认为0.8
  32. cropBoxResizable: true, //是否可以调整剪裁框的大小
  33. cropBoxMovable: true, //是否可以移动剪裁框
  34. crop: function (e) {
  35. $dataX.val(Math.round(e.x));
  36. $dataY.val(Math.round(e.y));
  37. $dataHeight.val(Math.round(e.height));
  38. $dataWidth.val(Math.round(e.width));
  39. $dataRotate.val(e.rotate);
  40. $dataScaleX.val(e.scaleX);
  41. $dataScaleY.val(e.scaleY);
  42. }
  43. };
  44. var originalImageURL = $image.attr('src');
  45. var uploadedImageName = '';
  46. var uploadedImageType = 'image/jpeg';
  47. var uploadedImageURL;
  48. // Cropper
  49. $image.on({
  50. ready: function (e) {
  51. //console.log(e.type);
  52. },
  53. cropstart: function (e) {
  54. //console.log(e.type, e.action);
  55. },
  56. cropmove: function (e) {
  57. //console.log(e.type, e.action);
  58. },
  59. cropend: function (e) {
  60. //console.log(e.type, e.action);
  61. },
  62. crop: function (e) {
  63. //console.log(e.type, e.x, e.y, e.width, e.height, e.rotate, e.scaleX, e.scaleY);
  64. },
  65. zoom: function (e) {
  66. //console.log(e.type, e.ratio);
  67. }
  68. }).cropper(options);
  69. // Buttons
  70. if (!$.isFunction(document.createElement('canvas').getContext)) {
  71. $('button[data-method="getCroppedCanvas"]').prop('disabled', true);
  72. }
  73. if (typeof document.createElement('cropper').style.transition === 'undefined') {
  74. $('button[data-method="rotate"]').prop('disabled', true);
  75. $('button[data-method="scale"]').prop('disabled', true);
  76. }
  77. // Download
  78. if (typeof $download[0].download === 'undefined') {
  79. $download.addClass('disabled');
  80. }
  81. // Methods
  82. $('.docs-buttons').on('click', '[data-method]', function () {
  83. var $this = $(this);
  84. var data = $this.data();
  85. var cropper = $image.data('cropper');
  86. var cropped;
  87. var $target;
  88. var result;
  89. if ($this.prop('disabled') || $this.hasClass('disabled')) {
  90. return;
  91. }
  92. if (cropper && data.method) {
  93. data = $.extend({}, data); // Clone a new one
  94. if (typeof data.target !== 'undefined') {
  95. $target = $(data.target);
  96. if (typeof data.option === 'undefined') {
  97. try {
  98. data.option = JSON.parse($target.val());
  99. } catch (e) {
  100. console.log(e.message);
  101. }
  102. }
  103. }
  104. cropped = cropper.cropped;
  105. switch (data.method) {
  106. case 'rotate': //旋转
  107. if (cropped && options.viewMode > 0) {
  108. $image.cropper('clear');
  109. }
  110. break;
  111. case 'getCroppedCanvas':
  112. if (uploadedImageType === 'image/jpeg') {
  113. if (!data.option) {
  114. data.option = {};
  115. }
  116. data.option.fillColor = '#fff';
  117. }
  118. break;
  119. }
  120. result = $image.cropper(data.method, data.option, data.secondOption);
  121. switch (data.method) {
  122. case 'rotate':
  123. if (cropped && options.viewMode > 0) {
  124. $image.cropper('crop');
  125. }
  126. break;
  127. case 'scaleX':
  128. case 'scaleY':
  129. $(this).data('option', -data.option);
  130. break;
  131. case 'getCroppedCanvas':
  132. if (result) {
  133. // Bootstrap's Modal
  134. $('#getCroppedCanvasModal').modal().find('.modal-body').html(result);
  135. if (!$download.hasClass('disabled')) {
  136. download.download = uploadedImageName;
  137. $download.attr('href', result.toDataURL(uploadedImageType));
  138. }
  139. }
  140. break;
  141. case 'destroy':
  142. if (uploadedImageURL) {
  143. URL.revokeObjectURL(uploadedImageURL);
  144. uploadedImageURL = '';
  145. $image.attr('src', originalImageURL);
  146. }
  147. break;
  148. }
  149. if ($.isPlainObject(result) && $target) {
  150. try {
  151. $target.val(JSON.stringify(result));
  152. } catch (e) {
  153. console.log(e.message);
  154. }
  155. }
  156. }
  157. });
  158. // Import image
  159. var $inputImage = $('#inputImage');
  160. if (URL) {
  161. $inputImage.change(function () {
  162. var files = this.files;
  163. var file;
  164. if (!$image.data('cropper')) {
  165. return;
  166. }
  167. if (files && files.length) {
  168. file = files[0];
  169. if (/^image\/\w+$/.test(file.type)) {
  170. uploadedImageName = file.name;
  171. uploadedImageType = file.type;
  172. if (uploadedImageURL) {
  173. URL.revokeObjectURL(uploadedImageURL);
  174. }
  175. uploadedImageURL = URL.createObjectURL(file);
  176. $image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
  177. $inputImage.val('');
  178. } else {
  179. window.alert('Please choose an image file.');
  180. }
  181. }
  182. });
  183. } else {
  184. $inputImage.prop('disabled', true).parent().addClass('disabled');
  185. }
  186. //上传图片
  187. $("#getCroppedCanvas").on("click", function () {
  188. var cas = $('#image').cropper('getCroppedCanvas');
  189. if(cas == null){
  190. alert("请选择图片");
  191. return false;
  192. }else{
  193. var base64url = cas.toDataURL('image/jpeg');
  194. $.ajax({
  195. url : 'wap_ajbj_upload_zm.htm',
  196. dataType:'json',
  197. type: "post",
  198. data: {
  199. fileName : uploadedImageName,
  200. imgBase64 : base64url
  201. },
  202. success: function (data) {
  203. if(data.result == 'success'){
  204. alert("上传成功");
  205. }
  206. }
  207. });
  208. }
  209. })
  210. });
  211. </script>
  212. </head>
  213. <body>
  214. <div class="container" style="margin-top: 10px;">
  215. <div class="row">
  216. <div class="col-md-9">
  217. <div class="img-container">
  218. <img id="image" >
  219. </div>
  220. </div>
  221. <div class="col-md-3">
  222. <div class="docs-preview clearfix">
  223. <div class="img-preview preview-lg"></div>
  224. </div>
  225. <div class="docs-data">
  226. <div class="input-group input-group-sm">
  227. <span class="input-group-prepend">
  228. <label class="input-group-text" for="dataWidth">宽度</label>
  229. </span>
  230. <input type="text" class="form-control" id="dataWidth" disabled>
  231. <span class="input-group-append">
  232. <span class="input-group-text">像素</span>
  233. </span>
  234. </div>
  235. <div class="input-group input-group-sm">
  236. <span class="input-group-prepend">
  237. <label class="input-group-text" for="dataHeight">高度</label>
  238. </span>
  239. <input type="text" class="form-control" id="dataHeight" disabled>
  240. <span class="input-group-append">
  241. <span class="input-group-text">像素</span>
  242. </span>
  243. </div>
  244. </div>
  245. </div>
  246. </div>
  247. <div class="row">
  248. <div class="col-md-9 docs-buttons">
  249. <div class="btn-group">
  250. <button type="button" class="btn btn-primary" data-method="rotate" data-option="-90" title="Rotate Left">
  251. <span class="docs-tooltip" data-animation="false" title="向左旋转">
  252. <span class="fa fa-rotate-left">向左旋转</span>
  253. </span>
  254. </button>
  255. <button type="button" class="btn btn-primary" data-method="rotate" data-option="90" title="Rotate Right">
  256. <span class="docs-tooltip" data-animation="false" title="向右旋转">
  257. <span class="fa fa-rotate-right">向右旋转</span>
  258. </span>
  259. </button>
  260. </div>
  261. <div class="btn-group">
  262. <label class="btn btn-primary btn-upload" for="inputImage" title="Upload image file">
  263. <input type="file" class="sr-only" id="inputImage" name="file" accept="image/*">
  264. <span class="docs-tooltip" data-animation="false" title="打开本地图片">
  265. <span class="fa fa-upload">选择图片</span>
  266. </span>
  267. </label>
  268. </div>
  269. <div class="btn-group btn-group-crop">
  270. <button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ "maxWidth": 4096, "maxHeight": 4096 }">
  271. <span class="docs-tooltip" data-animation="false" title="获取图片">
  272. 获取图片
  273. </span>
  274. </button>
  275. </div>
  276. <!-- 截取固定尺寸 -->
  277. <div class="btn-group btn-group-crop">
  278. <button type="button" class="btn btn-success" data-method="getCroppedCanvas" data-option="{ "width": 200, "height": 200 }">
  279. <span class="docs-tooltip" data-animation="false" title="200*200">
  280. 200*200
  281. </span>
  282. </button>
  283. </div>
  284. <div class="btn-group btn-group-crop">
  285. <button id="getCroppedCanvas" type="button" class="btn btn-success" >
  286. <span class="docs-tooltip" data-animation="false" title="上传图片">
  287. 上传图片
  288. </span>
  289. </button>
  290. </div>
  291. <!-- 获取图片浮窗 -->
  292. <div class="modal fade docs-cropped" id="getCroppedCanvasModal" aria-hidden="true" aria-labelledby="getCroppedCanvasTitle" role="dialog" tabindex="-1">
  293. <div class="modal-dialog">
  294. <div class="modal-content">
  295. <div class="modal-header">
  296. <h5 class="modal-title" id="getCroppedCanvasTitle">图片</h5>
  297. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  298. <span aria-hidden="true">×</span>
  299. </button>
  300. </div>
  301. <div class="modal-body"></div>
  302. <div class="modal-footer">
  303. <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
  304. <a class="btn btn-primary" id="download" href="javascript:void(0);" >下载</a>
  305. </div>
  306. </div>
  307. </div>
  308. </div>
  309. </div>
  310. </div>
  311. </div>
  312. </body>
  313. </html>

后台程序

  1. private String filePath = LxwmController.class.getResource("/").getPath().split("WEB-INF")[0]+ "upload/";
  2. @RequestMapping(value = "wap_ajbj_upload_zm.htm", method = {RequestMethod.GET, RequestMethod.POST })
  3. @ResponseBody
  4. public Map<String, Object> wap_ajbj_upload_zm(HttpServletRequest request) throws Exception {
  5. Map<String, Object> result = new HashMap<String, Object>();
  6. String fileName = request.getParameter("fileName");
  7. fileName = System.currentTimeMillis() + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
  8. String imgBase64 = request.getParameter("imgBase64");
  9. imgBase64 = imgBase64.split(",")[1];
  10. GenerateImage(imgBase64,filePath + "/ajbj/zm/"+fileName);
  11. result.put("result", "success");
  12. return result;
  13. }
  14. /**
  15. * @Description: 将base64编码字符串转换为图片
  16. * @param imgStr base64编码字符串
  17. * @param path 图片路径-具体到文件
  18. */
  19. public static boolean GenerateImage(String imgStr,String imgFilePath){
  20. if (imgStr == null) //图像数据为空
  21. return false;
  22. BASE64Decoder decoder = new BASE64Decoder();
  23. try{
  24. //Base64解码
  25. byte[] b = decoder.decodeBuffer(imgStr);
  26. for(int i=0;i<b.length;++i){
  27. if(b[i] < 0){//调整异常数据
  28. b[i] += 256;
  29. }
  30. }
  31. OutputStream out = new FileOutputStream(imgFilePath);
  32. out.write(b);
  33. out.flush();
  34. out.close();
  35. return true;
  36. }
  37. catch (Exception e){
  38. return false;
  39. }
  40. }

把裁剪的图片转化为blob上传

前台程序

  1. //上传图片js变更为
  2. $("#getCroppedCanvas").on("click", function () {
  3. var cas = $('#image').cropper('getCroppedCanvas');
  4. if(cas == null){
  5. alert("请选择图片");
  6. return false;
  7. }else{
  8. var blob = processData(cas.toDataURL());
  9. var formData = new FormData();
  10. formData.append('croppedImage', blob);
  11. formData.append('fileName', uploadedImageName);
  12. $.ajax({
  13. url : 'wap_ajbj_upload_zm.htm',
  14. type: "post",
  15. data: formData,
  16. processData: false,
  17. contentType: false,
  18. success: function (data) {
  19. if(data.result == 'success'){
  20. alert("上传成功");
  21. }
  22. }
  23. });
  24. }
  25. })
  26. //添加转化为二进制方法
  27. function processData(dataUrl) {
  28. var binaryString = window.atob(dataUrl.split(',')[1]);
  29. var arrayBuffer = new ArrayBuffer(binaryString.length);
  30. var intArray = new Uint8Array(arrayBuffer);
  31. for (var i = 0, j = binaryString.length; i < j; i++) {
  32. intArray[i] = binaryString.charCodeAt(i);
  33. }
  34. var data = [intArray],
  35. blob;
  36. try {
  37. blob = new Blob(data);
  38. } catch (e) {
  39. window.BlobBuilder = window.BlobBuilder ||
  40. window.WebKitBlobBuilder ||
  41. window.MozBlobBuilder ||
  42. window.MSBlobBuilder;
  43. if (e.name === 'TypeError' && window.BlobBuilder) {
  44. var builder = new BlobBuilder();
  45. builder.append(arrayBuffer);
  46. blob = builder.getBlob(imgType); // imgType为上传文件类型,即 file.type
  47. } else {
  48. console.log('版本过低,不支持上传图片');
  49. }
  50. }
  51. return blob;
  52. }

后台程序

  1. private String filePath = LxwmController.class.getResource("/").getPath().split("WEB-INF")[0]+ "upload/";
  2. @RequestMapping(value = "wap_ajbj_upload_zm.htm", method = {RequestMethod.GET, RequestMethod.POST })
  3. @ResponseBody
  4. public Map<String, Object> wap_ajbj_upload_zm(@RequestParam(value = "croppedImage",required = false)MultipartFile file, HttpServletRequest request) throws Exception {
  5. Map<String, Object> result = new HashMap<String, Object>();
  6. if(file != null && !file.isEmpty()){
  7. String filename = request.getParameter("fileName"); //获取文件的名字
  8. filename = new String(filename.getBytes("UTF-8"), "UTF-8");
  9. String suffix = filename.substring(filename.lastIndexOf(".") + 1);
  10. filename = System.currentTimeMillis() + "." + suffix;
  11. try {
  12. copyFileRename(file.getInputStream(), filename,filePath + "/ajbj/zm/");
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. result.put("result", "success");
  18. return result;
  19. }
  20. public static void copyFileRename(InputStream in, String fileName,String myFilePath) throws IOException {
  21. FileOutputStream fs = new FileOutputStream(myFilePath + fileName);
  22. byte[] buffer = new byte[1024 * 1024];
  23. int byteread = 0;
  24. while ((byteread = in.read(buffer)) != -1) {
  25. fs.write(buffer, 0, byteread);
  26. fs.flush();
  27. }
  28. fs.close();
  29. in.close();
  30. }

发表评论

表情:
评论列表 (有 0 条评论,390人围观)

还没有评论,来说两句吧...

相关阅读