2019独角兽企业重金招聘Python工程师标准>>>

需求:用户上传或者修改头像的时候先将图片裁剪,固定宽度和高度,这样在不同的情景下显示的时候不会出现压缩失真。

中间折腾过的方法:

1.smartCorp.js

国外一个大神写的,根据图像的饱和度裁剪最好看的照片,刚开始以为很好用的,在官网上下载了源码,demo跑起来还可以,但是裁剪成小图片的时候裁剪不了,项目是Java的,但是demo用的是PHP,我也不会PHP,也没有运行环境,最后放弃了。

2.JS素材网上下载的插件。也是一样的问题,裁剪成小图片的后台代码运行不了,而且样式也不好看,还是选择放弃。

3.JCorp.js 这也是国外的开源软件,第一眼看上去清新大方,有点意思。还有详尽的使用方法,不错不错。但是最核心的裁剪问题依然存在。有博客上用的是后台的Java代码裁剪,demo支持直接本地读取,和写入,没有问题,但是放在网页上,图片走服务器上传是很麻烦的一个问题,除了上传原图,还要返回裁剪后的图片base64码,这样子显示是没问题了 ,但是怎么上传到阿里云服务器又是问题了。找啊找,终于找到一个博客写的是用前端H5的<canvas>画布裁剪,不走服务器,很nice。于是乎直接放在项目里用了,集成好也没问题,很开心。开心了一分钟,然后,流文件怎么上传到阿里云服务器呢,翻遍了阿里云的社区和手册也没找到答案。然后简书上的一篇文章讲清楚了要怎么处理上传,搬过来,解决好了。最后还有一个问题,如何上传到网易云呢?翻了网易云的开发文档,用断点走了几遍js文件,找到了上传的文件格式,一遍一遍的试,最后也搞好了。超级超级开心的。以下是实现代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!doctype html>
<html>
<head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/>  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>  <meta name="description" id="description1" content="1">  <meta name="renderer" content="webkit">  <meta name="format-detection" content="telephone=no">  <title>图片上传</title>  <style type="text/css">  .jcrop-holder {  direction: ltr;  text-align: center;  margin: 0 auto;  /* IE10 touch compatibility */  -ms-touch-action: none;  }  /* Selection Border */  .jcrop-vline,  .jcrop-hline {  background: #ffffff url("Jcrop.gif");  font-size: 0;  position: absolute;  }  .jcrop-vline {  height: 100%;  width: 1px !important;  }  .jcrop-vline.right {  right: 0;  }  .jcrop-hline {  height: 1px !important;  width: 100%;  }  .jcrop-hline.bottom {  bottom: 0;  }  /* Invisible click targets */  .jcrop-tracker {  height: 100%;  width: 100%;  /* "turn off" link highlight */  -webkit-tap-highlight-color: transparent;  /* disable callout, image save panel */  -webkit-touch-callout: none;  /* disable cut copy paste */  -webkit-user-select: none;  }  /* Selection Handles */  .jcrop-handle {  background-color: #333333;  border: 1px #eeeeee solid;  width: 7px;  height: 7px;  font-size: 1px;  }  .jcrop-handle.ord-n {  left: 50%;  margin-left: -4px;  margin-top: -4px;  top: 0;  }  .jcrop-handle.ord-s {  bottom: 0;  left: 50%;  margin-bottom: -4px;  margin-left: -4px;  }  .jcrop-handle.ord-e {  margin-right: -4px;  margin-top: -4px;  right: 0;  top: 50%;  }  .jcrop-handle.ord-w {  left: 0;  margin-left: -4px;  margin-top: -4px;  top: 50%;  }  .jcrop-handle.ord-nw {  left: 0;  margin-left: -4px;  margin-top: -4px;  top: 0;  }  .jcrop-handle.ord-ne {  margin-right: -4px;  margin-top: -4px;  right: 0;  top: 0;  }  .jcrop-handle.ord-se {  bottom: 0;  margin-bottom: -4px;  margin-right: -4px;  right: 0;  }  .jcrop-handle.ord-sw {  bottom: 0;  left: 0;  margin-bottom: -4px;  margin-left: -4px;  }  /* Dragbars */  .jcrop-dragbar.ord-n,  .jcrop-dragbar.ord-s {  height: 7px;  width: 100%;  }  .jcrop-dragbar.ord-e,  .jcrop-dragbar.ord-w {  height: 100%;  width: 7px;  }  .jcrop-dragbar.ord-n {  margin-top: -4px;  }  .jcrop-dragbar.ord-s {  bottom: 0;  margin-bottom: -4px;  }  .jcrop-dragbar.ord-e {  margin-right: -4px;  right: 0;  }  .jcrop-dragbar.ord-w {  margin-left: -4px;  }  /* The "jcrop-light" class/extension */  .jcrop-light .jcrop-vline,  .jcrop-light .jcrop-hline {  background: #ffffff;  filter: alpha(opacity=70) !important;  opacity: .70!important;  }  .jcrop-light .jcrop-handle {  -moz-border-radius: 3px;  -webkit-border-radius: 3px;  background-color: #000000;  border-color: #ffffff;  border-radius: 3px;  }  /* The "jcrop-dark" class/extension */  .jcrop-dark .jcrop-vline,  .jcrop-dark .jcrop-hline {  background: #000000;  filter: alpha(opacity=70) !important;  opacity: 0.7 !important;  }  .jcrop-dark .jcrop-handle {  -moz-border-radius: 3px;  -webkit-border-radius: 3px;  background-color: #ffffff;  border-color: #000000;  border-radius: 3px;  }  /* Simple macro to turn off the antlines */  .solid-line .jcrop-vline,  .solid-line .jcrop-hline {  background: #ffffff;  }  /* Fix for twitter bootstrap et al. */  .jcrop-holder img,  img.jcrop-preview {  max-width: none;  }  .uploadPics {  position: relative;  width: 380px;  background-color: #fff;  height: 460px;  overflow: hidden;  }  .uploadPics > img {  position: absolute;  top: 20px;  right: 10px;  cursor: pointer;  }  .uploadPics .picTil {  padding: 20px;  font-size: 16px;  color: #323232;  border-bottom: 1px solid #f3f3f3;  }  .uploadPics .picCont {  margin: 20px;  padding: 15px;  width: 300px;  height: 337px;  background-color: #f2f2f5;  }  .uploadPics .picCont > p {  margin-top: 20px;  text-align: center;  }  .uploadPics .picFooter {  text-align: center;  }  .uploadPics .picFooter{  display: inline-block;  margin: 20px;  width: 130px;  height: 35px;  font-size: 18px;  line-height: 35px;  color: #fff;  border-radius: 5px;  cursor: pointer;  }  .uploadPics .picFooter .upload {  background-color: #aaa;  }  .uploadPics .picFooter .confirm {  background-color: #ed2828;  }  #myCan{  position: absolute;  top: 86px;  right: 110px;  } .info{position: absolute;  top: 16px;  right: 196px;  }</style>  <link rel="stylesheet" href="<%=request.getContextPath()%>/Jcrop/css/jquery.Jcrop.css" type="text/css" /><script type="text/javascript" src="<%=request.getContextPath()%>/Jcrop/js/jquery.Jcrop.js"></script>
</head>
<body>
<div id="showbg" style="display: none;">
<div class="uploadPics">  <div class="picCont" style="width:300px;height:300px;margin:20px auto 0;padding:0;" >  <div id=imgfield  style=overflow:hidden;width:100%;height:100% ></div>  </div>  <div class="picFooter">  <input type="file" accept=".jpg,.jpeg,.png,.gif" id="fileimg" name="fileimg" style="display:none" onchange="imgchange()" />  <span class="layui-btn layui-btn-sm"  onclick="getimg()">上传原图</span>  <!-- <span class="btn confirm" onclick="subform()">确认</span>   --></div>  </div>
<div class="info">裁剪后图片:<br>图片大小:200 × 200</div>
<canvas id="myCan" width="200" height="200"></canvas>
</div>  </body>  <script type="text/javascript">  //上传的文件名var fileName ="";
//  var nim = '';function subform() {  if($("#imgfield").html()){  var ossurl = "";//获取裁剪完后的base64图片url,转换为blob  var urlData=document.getElementById("myCan").toDataURL();  var blob = dataURLtoBlob(urlData);  // blob转arrayBuffervar reader = new FileReader();reader.readAsArrayBuffer(blob);reader.onload = function (event) {var opts = {url : "web?module=stwmgr&action=Advertisement&method=getOSSSecurityToken&tokenId=<%=request.getParameter("tokenId")%>",type : "POST",processData : false,contentType : false,dataType : "json",async:false,success : function(token) {var client = new OSS.Wrapper({accessKeyId : token.accessKeyId,//keyaccessKeySecret : token.accessKeySecret,//密码、stsToken : token.securityToken,region : token.ossRegion,//阿里云服务器地址bucket : token.ossBucket,//上传的到的文件夹secure:true});var key = "stw_mgr/images/portrait_images/" + getCurrentDate() + getExtension(fileName);//arrayBuffer转buffervar buffer = new OSS.Buffer(event.target.result);//上传接口改为putclient.put(key, buffer).then(function(result) {console.log(result);var url = client.signatureUrl(key);$("input[name='portraitUri']").val(key);$("#portraitImage").attr("src", url);console.log(url);ossurl = url;}).catch(function(err) {console.log(err.message);});}};$.ajax(opts);}// uploadTitleImage(blob);          //网易云信上传nim.sendFile({scene: 'p2p',to: 'account',type: 'image',blob: blob,// wxFilePath: neteaseFile,beginupload: function(upload) {// - 如果开发者传入 fileInput, 在此回调之前不能修改 fileInput// - 在此回调之后可以取消图片上传, 此回调会接收一个参数 `upload`, 调用 `upload.abort();` 来取消文件上传},uploadprogress: function(obj) {console.log('文件总大小: ' + obj.total + 'bytes');console.log('已经上传的大小: ' + obj.loaded + 'bytes');console.log('上传进度: ' + obj.percentage);console.log('上传进度文本: ' + obj.percentageText);},uploaddone: function(error, file) {console.log(file);$('#neteaseUri').val(file.url);console.log('上传' + (!error?'成功':'失败'));}});}  }  function getimg() {  $("#fileimg").click();  }  function imgchange() {  var localimg = $("#fileimg").get(0).files[0];  if(!localimg){  return;  }  fileName = localimg.name;  var fileSize = localimg.size;  var fileType=fileName.substring(fileName.lastIndexOf('.'),fileName.length).toLowerCase();  if(fileType!='.gif' && fileType!='.jpeg' && fileType!='.png' && fileType!='.jpg')  {  alert("上传失败,请上传jpg,jpeg,png格式的图片");  return;  }  var size=10*1024*1024;  if(fileSize>size){  alert("上传失败,请上传10MB以内的图片。");  return;  }  var reader=new FileReader();  //将文件读取为DataURL  reader.readAsDataURL(localimg);  reader.onload= function (e) {  var localimghtml = '<img id="cropbox" src="' +  e.target.result + '" >';  $("#imgfield").html(localimghtml);  initJcrop();  };  }  function initJcrop(){  $('#cropbox').Jcrop({  onSelect: updateCoords,  aspectRatio: 1,  boxWidth: 300,  boxHeight: 300  }, function () {  //图片实际尺寸  var bb = this.getBounds();  var bWidth= Number(bb[0]) / 2;  var bHeight= Number(bb[1]) / 2;  this.setSelect([0, 0, bWidth,bHeight]);  var ss = this.getWidgetSize();  var aheight = (300 - Number(ss[1])) / 2 + "px";  $(".jcrop-holder").css("margin-top", aheight);  });  }  function updateCoords(c){
//      console.log(c);  var img=document.getElementById("cropbox");  var ctx=document.getElementById("myCan").getContext("2d");  //img,开始剪切的x,Y坐标宽高,放置图像的x,y坐标宽高。  ctx.drawImage(img,c.x,c.y, c.w, c.h,0,0,200,200);  }  //**dataURL to blob**  function dataURLtoBlob(dataurl) {  var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],  bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);  while (n--) {  u8arr[n] = bstr.charCodeAt(n);  }  return new Blob([u8arr], { type: mime });  }  </script>  </html> 
//点击头像框触发事件
$("#portraitImage").click(function(){var c=document.getElementById("myCan");  var cxt=c.getContext("2d");  cxt.clearRect(0,0,c.width,c.height); var porsrc = this.src;var orginimg = '<img id="cropbox" src="" crossorigin="Anonymous" >';       //" crossorigin="Anonymous"//var image = new Image();//image.setAttribute("crossOrigin",'Anonymous')//image.crossOrigin = "Anonymous";//image.src = porsrc;$("#imgfield").html(orginimg);         //把原有的头像图片添加到可编辑框里$("#cropbox").attr("src",porsrc);//初始化插件方法initJcrop(); layer.open({type: 1,scrollbar: false,title: ['头像裁剪框', 'font-size:16px;'],area: ['800px', '500px'],btn: ['保存'],tipsMore: true,content: $("#showbg"),yes: function(index, layero){subform();$('#showbg').css('display','none');layer.closeAll();},cancel: function(){ $('#showbg').css('display','none');}});});

最后想了一个改进的地方,就是之前已经有头像的用户,可能会复用以前的头像,所以点击修改的时候要把原来的图片带到图片处理框里。这里遇到了图片的跨越请求问题。解决办法是在img标签添加一个属性:crossorigin="Anonymous"。

前后大概5天的时间做了这么一个小小的功能,收获了图像处理的知识,虽然理解上并没有很深,但是能运用起来,也蛮有成就感的了。记录下探索的历程。望更进一步。

JCrop官网地址:http://deepliquid.com/content/Jcrop_Download.html

转载于:https://my.oschina.net/u/3476497/blog/1833713

图片裁剪工具——JCorp相关推荐

  1. android 自定义图片裁剪,Android图片裁剪工具封装

    笔者从零开始开发Android,而且是跳过java直接使用kotlin开发,这其中的好处是可以避开java这门传统语言诸多的潜规则,难处是相比资深Android开发者少了许多可以现用的工具库.比如An ...

  2. Java之图片裁剪工具类-yellowcong

    对于图片,我们需要做的大致有,图片裁剪,添加水印和文字的操作,图片裁剪工具这个只包含了图片裁剪,后面的水印功能我会陆续添加上来 图片裁剪工具 package com.yellowcong.utils; ...

  3. JAVA图片裁剪工具类

    JAVA图片裁剪工具类: <span style="font-size:14px;">package org.oms.avatar.util;import java.a ...

  4. android启动系统的图片裁剪工具

    android启动系统的图片裁剪工具的方法 /*** 裁剪图片* @param activity 启动裁剪图片的Activity* @param uri 图片的uri路径* @param savePa ...

  5. 微信html5图片裁切,微信小程序图片裁剪工具we-cropper

    微信小程序图片裁剪工具we-cropper 一款灵活小巧的canvas图片裁剪器 在线体验 Feature 实用的API 灵活的钩子函数 多场景的demo可供参考: 常规裁剪 上传裁剪头像 裁剪网络图 ...

  6. 图片裁剪工具之cropper.js

    图片裁剪工具之cropper.js cropper.js 示例Demo 具体使用示例 cropper.js Cropper.js 是一款非常强大却又简单的图片裁剪工具,它可以进行非常灵活的配置,支持手 ...

  7. cropper:图片裁剪工具

    1.图片裁剪工具:基本初始化使用: $('#image').cropper({aspectRatio: 1 / 1, // 纵横比:正方形preview: '.img-preview' // 指定预览 ...

  8. 图片裁剪工具vueCropper跨域解决

    图片裁剪工具vueCropper跨域解决 1.报错原因:本项目的图片放在亚马逊,需求是直接拿到网络图片进行裁剪 2.解决:将图片转化成base64 Vue.prototype.getBase64Img ...

  9. Android调用手机图库选择图片并调用手机的图片裁剪工具

    /*** 获得图库图片回调标识*/public static final int GET_PIC_FROM_GALLERY = 0X100;/*** 调用手机工具编辑图片标识*/public stat ...

最新文章

  1. sql server 2008数据导入Oracle方法
  2. 【转载】c#类的成员初始化顺序
  3. 2019ICPC(南京) - Greedy Sequence(线段树)
  4. wordpress 每段首行空两格
  5. Android Button字母自动全部大写的问题
  6. 概率图模型笔记(三)条件随机场(CRF)基础
  7. 使用回收站主键名、索引名问题
  8. java 中高级面试题_Java中高级面试题
  9. java resourcebundle_java.util.ResourceBundle使用详解
  10. 求大于某一正整数的最小质数
  11. 支付宝 alipay.fund.trans.uni.transfer(单笔转账接口)功能整合
  12. 【Matlab】前馈控制
  13. 2019年安徽省程序设计大赛题解
  14. 针式PKM初级应用:针式PKM更适合管理什么样的文件
  15. 论文分享——Dynamic graph attention for referring expression comprehension
  16. 解决python关于UnicodeEncodeError: 'gbk' codec can't encode character '\xa3'报错的问题
  17. 我在谷歌大脑见习机器学习的一年:Node.js创始人的尝试笔记
  18. 模拟苹果验证服务器,[原创]苹果 gsa 服务器login 算法
  19. unity塔防游戏怪物转向_野生防御塔游戏下载-野生防御塔游戏安卓版 v1.0
  20. 自己经常用的一些电影下载网址

热门文章

  1. python PEP8 记录
  2. 【论文解读】Optimizing FPGA-based Accelerator Design for Deep Convolutional Neural Networks
  3. 负数的补码和原码转换
  4. nCode:DesignLife案例教程二十
  5. 医疗器械管理系统-医疗器械进销存管理系统-盘谷医疗
  6. 39.SSH远程终端连接工具
  7. ubuntu c语言调用串口,ubuntu 下使用串口工具(呕心沥血整理调试成功)
  8. 字符串去重复的几种方法
  9. 00 59秒计时器仿真c语言源程序,单片机0059_秒计时器.doc
  10. c++ 三只小猪称体重(二)