标签:
最近有个微信项目的用户个人中心模块中,客户要求用户头像不仅仅只是上传图片,还需要能对图片进行裁剪。考虑到flash在IOS和Android上的兼容性问题,于是想着能从js这块入手,在网上发现了devotion博主写的《适应各浏览器图片裁剪无刷新上传js插件》文章,从中受到些许启发,以此为参考,进行了简单的修改。
新建一个页面,代码如下:
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head id="Head1" runat="server"> 3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 4 <title>图片裁剪</title> 5 <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" /> 6 <link href="../css/jquery.Jcrop.min.css" rel="stylesheet" /> 7 <script type="text/javascript" src="../js/jquery-1.7.1.min.js"></script> 8 <script type="text/javascript" src="../js/jquery.Jcrop.min.js"></script> 9 <script type="text/javascript" src="../js/imageCropperUpload.js"></script> 10 <style type="text/css"> 11 #test 12 { 13 width: 100%; 14 height: 100%; 15 background-color: #000; 16 position: absolute; 17 top: 0; 18 left: 0; 19 z-index: 2; 20 opacity: 0.8; 21 /*兼容IE8及以下版本浏览器*/ 22 filter: alpha(opacity=60); 23 display: none; 24 } 25 26 #fileList 27 { 28 width: 100%; 29 height: 500px; 30 /*background-color: #FF0;*/ 31 margin: auto; 32 position: absolute; 33 z-index: 3; 34 top: 0; 35 bottom: 0; 36 left: 0; 37 right: 0; 38 display: none; 39 text-align: center; 40 } 41 #divtest { 42 position: absolute; 43 z-index: 3; 44 display: none; 45 bottom: 10px; 46 left: 0; 47 width: 100%; 48 } 49 #divCancel 50 { 51 float: left; 52 width: 48px; 53 height: 32px; 54 line-height: 32px; 55 margin: 10px 20px; 56 background-color: #fff; 57 text-align: center; 58 cursor: pointer; 59 display: block; 60 } 61 #divConfirm 62 { 63 float: right; 64 width: 48px; 65 height: 32px; 66 line-height: 32px; 67 margin: 10px 20px; 68 background-color: #fff; 69 text-align: center; 70 cursor: pointer; 71 display: block; 72 } 73 </style> 74 <script type="text/javascript"> 75 $(function () { 76 var btn = $("#selectFile"); 77 btn.click(function () { 78 $("#test").show(); 79 $("#fileList").show(); 80 $("#divtest").show(); 81 $("#divCancel").show(); 82 $("#divConfirm").show(); 83 }); 84 85 $("#divCancel").click(function () { 86 $("#test").hide(); 87 $("#fileList").hide(); 88 $("#divtest").hide(); 89 }); 90 $("#divConfirm").click(function () { 91 $("#files").click(); 92 }); 93 94 btn.cropperUpload({ 95 url: "../ajax/UploadPersonImage.ashx",//服务端处理图片 96 fileSuffixs: ["jpg", "png", "bmp"], 97 errorText: "{0}", 98 onComplete: function (msg) { 99 $("#divCancel").hide(); 100 $("#divConfirm").hide(); 101 if (msg == "false") { 102 alert("上传失败!"); 103 return; 104 } 105 $("#testimg").attr("src", msg); 106 }, 107 cropperParam: {//Jcrop参数设置,除onChange和onSelect不要使用,其他属性都可用 108 maxSize: [500, 300], //不要小于50,如maxSize:[40,24] 109 minSize: [300, 150], //不要小于50,如minSize:[40,24] 110 bgColor: "black", 111 bgOpacity: .4, 112 allowResize: true, 113 allowSelect: true, 114 animationDelay: 50 115 }, 116 perviewImageElementId: "fileList", //设置预览图片的元素id 117 perviewImgStyle: { width: ‘100%‘, height: ‘500px‘, border: ‘1px solid #ebebeb‘}//设置预览图片的样式 118 }); 119 120 var upload = btn.data("uploadFileData"); 121 122 $("#files").click(function () { 123 upload.submitUpload(); 124 $("#test").hide(); 125 $("#fileList").hide(); 126 $("#divtest").hide(); 127 }); 128 }); 129 </script> 130 </head> 131 <body> 132 <form id="form1" runat="server"> 133 <!-- 文件上传 start --> 134 <div style="width: 100%; float: left"> 135 <input id="selectFile" type="button" value="选择文件" /> 136 <input id="files" type="button" value="上传截图" style="display: none;" /> 137 </div> 138 <!-- 文件上传 end --> 139 140 <!-- 图片上传后展示的地方 start --> 141 <div id="testdiv" style="margin-top: 10px; width: 100%;"> 142 <img alt="" src="" id="testimg" /> 143 </div> 144 <!-- 图片上传后展示的地方 end --> 145 146 <!-- 遮罩层 start --> 147 <div id="test"></div> 148 <div id="fileList"> 149 </div> 150 <div id="divtest"> 151 <div id="divCancel">取消</div> 152 <div id="divConfirm">确定</div> 153 </div> 154 <!-- 遮罩层 end --> 155 </form> 156 </body> 157 </html>
页面中jQuery.Jcrop.min.css和jquery.Jcrop.min.js是Jcrop插件必须的一个样式表文件和js文件,jquery可以自行下载,然后后面的imageCropperUpload.js文件是devotion博主写的插件,我自己简单的修改了一下,注意引用顺序不要弄错了,否则不起作用。
1 (function ($) { 2 var defaultSettings = { 3 url: "uploadImg/", //上传地址 4 fileSuffixs: ["jpg", "png"], //允许上传的文件后缀名列表 5 errorText: "不能上传后缀为 {0} 的文件!", //错误提示文本,其中{0}将会被上传文件的后缀名替换 6 onCheckUpload: function (text) { //上传时检查文件后缀名不包含在fileSuffixs属性中时触发的回调函数,(text为错误提示文本) 7 }, 8 onComplete: function (msg) { //上传完成后的回调函数[不管成功或失败,它都将被触发](msg为服务端的返回字符串) 9 alert(msg); 10 }, 11 12 onChosen: function (file, obj, fileSize, errorTxt) { /*选择文件后的回调函数,(file为选中文件的本地路径;obj为当前的上传控件实例, 13 fileSize为上传文件大小,单位KB[只有在isFileSize为true时,此参数才有值], 14 errorTxt为获取文件大小时的错误文本提示) */ 15 //alert(file); 16 }, 17 cropperParam: {}, //图片截取参数设置,此参数即为Jcrop插件参数 18 isFileSize: false,//是否获取文件大小 19 perviewImageElementId: "",//用于预览上传图片的元素id(请传入一个div元素的id) 20 21 perviewImgStyle: null//用于设置图片预览时的样式(可不设置,在不设置的情况下多文件上传时只能显示一张图片),如{ width: ‘100px‘, height: ‘100px‘, border: ‘1px solid #ebebeb‘ } 22 }; 23 24 25 $.fn.cropperUpload = function (settings) { 26 27 settings = $.extend({}, defaultSettings, settings || {}); 28 29 return this.each(function () { 30 var self = $(this); 31 32 var upload = new UploadAssist(settings); 33 34 upload.createIframe(this); 35 36 //绑定当前按钮点击事件 37 self.bind("click", function (e) { 38 upload.chooseFile(); 39 }); 40 41 //将上传辅助类的实例,存放到当前对象中,方便外部获取 42 self.data("uploadFileData", upload); 43 44 //创建的iframe中的那个iframe,它的事件需要延迟绑定 45 window.setTimeout(function () { 46 $(upload.getIframeContentDocument().body).find("input[type=‘file‘]").change(function () { 47 if (!this.value) return; 48 var fileSuf = this.value.substring(this.value.lastIndexOf(".") + 1); 49 50 51 //检查是否为允许上传的文件 52 if (!upload.checkFileIsUpload(fileSuf, upload.settings.fileSuffixs)) { 53 upload.settings.onCheckUpload(upload.settings.errorText.replace("{0}", fileSuf)); 54 return; 55 } 56 57 if (upload.settings.isFileSize) { 58 var size = perviewImage.getFileSize(this, upload.getIframeContentDocument()); 59 var fileSize, errorTxt; 60 if (size == "error") { 61 errorTxt = upload.errorText; 62 } else { 63 fileSize = size; 64 } 65 //选中后的回调 66 upload.settings.onChosen(this.value, this, fileSize, errorTxt); 67 } else { 68 //选中后的回调 69 upload.settings.onChosen(this.value, this); 70 } 71 72 73 //是否开启了图片预览 74 if (upload.settings.perviewImageElementId) { 75 var main = perviewImage.createPreviewElement("closeImg", this.value, upload.settings.perviewImgStyle); 76 $("#" + upload.settings.perviewImageElementId).append(main); 77 var div = $(main).children("div").get(0); 78 79 perviewImage.beginPerview(this, div, upload.getIframeContentDocument(), upload); 80 $("#fileList").children().children("div").css("height", "100%").css("border", "none"); 81 } 82 }); 83 84 //为创建的iframe内部的iframe绑定load事件 85 $(upload.getIframeContentDocument().body.lastChild).on("load", function () { 86 var dcmt = upload.getInsideIframeContentDocument(); 87 upload.submitStatus = true; 88 if (dcmt.body.innerHTML) { 89 90 91 if (settings.onComplete) { 92 settings.onComplete(dcmt.body.innerHTML); 93 } 94 95 96 dcmt.body.innerHTML = ""; 97 } 98 }); 99 }, 100); 100 }); 101 }; 102 })(jQuery); 103 104 105 //上传辅助类 106 function UploadAssist(settings) { 107 //保存设置 108 this.settings = settings; 109 //创建的iframe唯一名称 110 this.iframeName = "upload" + this.getTimestamp(); 111 //提交状态 112 this.submitStatus = true; 113 //针对IE上传获取文件大小时的错误提示文本 114 this.errorText = "请设置浏览器一些参数后再上传文件,方法如下(设置一次即可):\n请依次点击浏览器菜单中的\n‘工具->Internet选项->安全->可信站点->自定义级别‘\n在弹出的自定义级别窗口中找到 ‘ActiveX控件和插件‘ 项,将下面的子项全部选为 ‘启用‘ 后,点击确定。\n此时不要关闭当前窗口,再点击 ‘站点‘ 按钮,在弹出的窗口中将下面复选框的 ‘√‘ 去掉,然后点击 ‘添加‘ 按钮并关闭当前窗口。\n最后一路 ‘确定‘ 完成并刷新当前页面。"; 115 116 this.jcropApi; 117 return this; 118 } 119 UploadAssist.prototype = { 120 //辅助类构造器 121 constructor: UploadAssist, 122 123 //创建iframe 124 createIframe: function (/*插件中指定的dom对象*/elem) { 125 126 var html = "<html>" 127 + "<head>" 128 + "<title>upload</title>" 129 + "<script>" 130 + "function getDCMT(){return window.frames[‘dynamic_creation_upload_iframe‘].document;}" 131 + "</" + "script>" 132 + "</head>" 133 + "<body>" 134 + "<form method=‘post‘ target=‘dynamic_creation_upload_iframe‘ enctype=‘multipart/form-data‘ action=‘" + this.settings.url + "‘>" 135 + "<input type=‘text‘ id=‘x1‘ name=‘x1‘ />" 136 + "<input type=‘text‘ id=‘y1‘ name=‘y1‘ />" 137 + "<input type=‘text‘ id=‘x2‘ name=‘x2‘ />" 138 + "<input type=‘text‘ id=‘y2‘ name=‘y2‘ />" 139 + "<input type=‘text‘ id=‘w‘ name=‘w‘ />" 140 + "<input type=‘text‘ id=‘h‘ name=‘h‘ />" 141 + "<input type=‘text‘ id=‘maxW‘ name=‘maxW‘ />" 142 + "<input type=‘text‘ id=‘maxH‘ name=‘maxH‘ />" 143 + "<input type=‘file‘ name=‘fileUpload‘ />" 144 + "</form>" 145 + "<iframe name=‘dynamic_creation_upload_iframe‘></iframe>" 146 + "</body>" 147 + "</html>"; 148 149 150 this.iframe = $("<iframe name=‘" + this.iframeName + "‘></iframe>")[0]; 151 this.iframe.style.width = "0px"; 152 this.iframe.style.height = "0px"; 153 this.iframe.style.border = "0px solid #fff"; 154 this.iframe.style.margin = "0px"; 155 elem.parentNode.insertBefore(this.iframe, elem); 156 var iframeDocument = this.getIframeContentDocument(); 157 iframeDocument.write(html); 158 }, 159 160 //获取时间戳 161 getTimestamp: function () { 162 return (new Date()).valueOf(); 163 }, 164 //设置图片缩放的最大高宽 165 setMaxWidthAndHeight: function (/*最大宽*/maxW,/*最大高*/maxH) { 166 this.getElement("maxW").value = maxW; 167 this.getElement("maxH").value = maxH; 168 }, 169 //设置图片截取参数 170 setImageCropperObj: function (/*图片截取对象*/obj) { 171 this.getElement("x1").value = obj.x; 172 this.getElement("y1").value = obj.y; 173 this.getElement("x2").value = obj.x2; 174 this.getElement("y2").value = obj.y2; 175 this.getElement("w").value = obj.w; 176 this.getElement("h").value = obj.h; 177 }, 178 //获取创建的iframe中的元素 179 getElement: function (id) { 180 var dcmt = this.getIframeContentDocument(); 181 return dcmt.getElementById(id); 182 }, 183 //获取创建的iframe中的document对象 184 getIframeContentDocument: function () { 185 return this.iframe.contentDocument || this.iframe.contentWindow.document; 186 }, 187 188 //获取创建的iframe所在的window对象 189 getIframeWindow: function () { 190 return this.iframe.contentWindow || this.iframe.contentDocument.parentWindow; 191 }, 192 193 //获取创建的iframe内部iframe的document对象 194 getInsideIframeContentDocument: function () { 195 return this.getIframeWindow().getDCMT(); 196 }, 197 198 //获取上传input控件 199 getUploadInput: function () { 200 var inputs = this.getIframeContentDocument().getElementsByTagName("input"); 201 var uploadControl; 202 this.forEach(inputs, function () { 203 if (this.type === "file") { 204 uploadControl = this; 205 return false; 206 } 207 }); 208 return uploadControl; 209 }, 210 211 //forEach迭代函数 212 forEach: function (/*数组*/arr, /*代理函数*/fn) { 213 var len = arr.length; 214 for (var i = 0; i < len; i++) { 215 var tmp = arr[i]; 216 if (fn.call(tmp, i, tmp) == false) { 217 break; 218 } 219 } 220 }, 221 222 //提交上传 223 submitUpload: function () { 224 if (!this.submitStatus) return; 225 226 this.submitStatus = false; 227 228 this.getIframeContentDocument().forms[0].submit(); 229 }, 230 231 //检查文件是否可以上传 232 checkFileIsUpload: function (fileSuf, suffixs) { 233 234 var status = false; 235 this.forEach(suffixs, function (i, n) { 236 if (fileSuf.toLowerCase() === n.toLowerCase()) { 237 status = true; 238 return false; 239 } 240 }); 241 return status; 242 }, 243 244 245 //选择上传文件 246 chooseFile: function () { 247 if (this.settings.perviewImageElementId) { 248 $("#" + this.settings.perviewImageElementId).empty(); 249 } 250 251 var uploadfile = this.getUploadInput(); 252 $(uploadfile).val("").click(); 253 } 254 }; 255 256 //图片预览操作 257 var perviewImage = { 258 timers: [], 259 //获取预览元素 260 getElementObject: function (elem) { 261 if (elem.nodeType && elem.nodeType === 1) { 262 return elem; 263 } else { 264 return document.getElementById(elem); 265 } 266 }, 267 //开始图片预览 268 beginPerview: function (/*文件上传控件实例*/file, /*需要显示的元素id或元素实例*/perviewElemId, /*上传页面所在的document对象*/ dcmt, /*上传辅助类实例*/upload) { 269 this.imageOperation(file, perviewElemId, dcmt, upload); 270 }, 271 //图片预览操作 272 imageOperation: function (/*文件上传控件实例*/file, /*需要显示的元素id或元素实例*/perviewElemId, /*上传页面所在的document对象*/ dcmt, /*上传辅助类实例*/upload) { 273 for (var t = 0; t < this.timers.length; t++) { 274 window.clearInterval(this.timers[t]); 275 } 276 this.timers.length = 0; 277 278 var tmpParams = { 279 onChange: function (c) { 280 upload.setImageCropperObj(c); 281 }, 282 onSelect: function (c) { 283 upload.setImageCropperObj(c); 284 } 285 }; 286 var sWidth = 50, sHeight = 50; 287 if (upload.settings.cropperParam.minSize) { 288 var size = upload.settings.cropperParam.minSize; 289 sWidth = size[0] > sWidth ? size[0] : sWidth; 290 sHeight = size[1] > sHeight ? size[1] : sHeight; 291 } 292 var params = $.extend({}, tmpParams, upload.settings.cropperParam || {}); 293 294 var preview_div = this.getElementObject(perviewElemId); 295 296 var MAXWIDTH = preview_div.clientWidth; 297 var MAXHEIGHT = preview_div.clientHeight; 298 299 upload.setMaxWidthAndHeight(MAXWIDTH, MAXHEIGHT); 300 301 if (file.files && file.files[0]) { //此处为Firefox,Chrome以及IE10的操作 302 preview_div.innerHTML = ""; 303 var img = document.createElement("img"); 304 preview_div.appendChild(img); 305 img.style.visibility = "hidden"; 306 img.onload = function () { 307 var rect = perviewImage.clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight); 308 img.style.width = rect.width + ‘px‘; 309 img.style.height = rect.height + ‘px‘; 310 img.style.visibility = "visible"; 311 var offsetWidth = (rect.width / 2) - (sWidth / 2); 312 var offsetHeight = (rect.height / 2) - (sHeight / 2); 313 var obj = { 314 x: offsetWidth, 315 y: offsetHeight, 316 x2: offsetWidth + sWidth, 317 y2: offsetHeight + sHeight, 318 w: sWidth, 319 h: sHeight 320 }; 321 322 $(img).Jcrop(params, function () { 323 upload.jcropApi = this; 324 325 this.animateTo([obj.x, obj.y, obj.x2, obj.y2]); 326 upload.setImageCropperObj(obj); 327 }); 328 }; 329 330 var reader = new FileReader(); 331 reader.onload = function (evt) { 332 img.src = evt.target.result; 333 }; 334 reader.readAsDataURL(file.files[0]); 335 } else { //此处为IE6,7,8,9的操作 336 file.select(); 337 var src = dcmt.selection.createRange().text; 338 339 var div_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=‘scale‘,src=‘" + src + "‘)"; 340 var img_sFilter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=‘image‘,src=‘" + src + "‘)"; 341 342 preview_div.innerHTML = ""; 343 var img = document.createElement("div"); 344 preview_div.appendChild(img); 345 img.style.filter = img_sFilter; 346 img.style.visibility = "hidden"; 347 img.style.width = "100%"; 348 img.style.height = "100%"; 349 350 function setImageDisplay() { 351 var rect = perviewImage.clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight); 352 preview_div.innerHTML = ""; 353 var div = document.createElement("div"); 354 div.style.width = rect.width + ‘px‘; 355 div.style.height = rect.height + ‘px‘; 356 div.style.filter = div_sFilter; 357 var offsetWidth = (rect.width / 2) - (sWidth / 2); 358 var offsetHeight = (rect.height / 2) - (sHeight / 2); 359 var obj = { 360 x: offsetWidth, 361 y: offsetHeight, 362 x2: offsetWidth + sWidth, 363 y2: offsetHeight + sHeight, 364 w: sWidth, 365 h: sHeight 366 }; 367 preview_div.appendChild(div); 368 $(div).Jcrop(params, function () { 369 upload.jcropApi = this; 370 this.animateTo([obj.x, obj.y, obj.x2, obj.y2]); 371 upload.setImageCropperObj(obj); 372 }); 373 } 374 375 //图片加载计数 376 var tally = 0; 377 378 var timer = window.setInterval(function () { 379 if (img.offsetHeight != MAXHEIGHT) { 380 window.clearInterval(timer); 381 setImageDisplay(); 382 } else { 383 tally++; 384 } 385 //如果超过两秒钟图片还不能加载,就停止当前的轮询 386 if (tally > 20) { 387 window.clearInterval(timer); 388 setImageDisplay(); 389 } 390 }, 100); 391 392 this.timers.push(timer); 393 } 394 }, 395 //按比例缩放图片 396 clacImgZoomParam: function (maxWidth, maxHeight, width, height) { 397 var param = { width: width, height: height }; 398 if (width > maxWidth || height > maxHeight) { 399 var rateWidth = width / maxWidth; 400 var rateHeight = height / maxHeight; 401 402 if (rateWidth > rateHeight) { 403 param.width = maxWidth; 404 param.height = Math.round(height / rateWidth); 405 } else { 406 param.width = Math.round(width / rateHeight); 407 param.height = maxHeight; 408 } 409 } 410 411 param.left = Math.round((maxWidth - param.width) / 2); 412 param.top = Math.round((maxHeight - param.height) / 2); 413 return param; 414 }, 415 //创建图片预览元素 416 createPreviewElement: function (/*关闭图片名称*/name, /*上传时的文件名*/file, /*预览时的样式*/style) { 417 var img = document.createElement("div"); 418 img.title = file; 419 img.style.overflow = "hidden"; 420 for (var s in style) { 421 img.style[s] = style[s]; 422 } 423 424 //var text = document.createElement("div"); 425 //text.style.width = style.width; 426 //text.style.overflow = "hidden"; 427 //text.style.textOverflow = "ellipsis"; 428 //text.style.whiteSpace = "nowrap"; 429 //text.innerHTML = file; 430 431 var main = document.createElement("div"); 432 main.appendChild(img); 433 //main.appendChild(text); 434 return main; 435 }, 436 437 //获取上传文件大小 438 getFileSize: function (/*上传控件dom对象*/file, /*上传控件所在的document对象*/dcmt) { 439 var fileSize; 440 if (file.files && file.files[0]) { 441 fileSize = file.files[0].size; 442 } else { 443 file.select(); 444 var src = dcmt.selection.createRange().text; 445 try { 446 var fso = new ActiveXObject("Scripting.FileSystemObject"); 447 var fileObj = fso.getFile(src); 448 fileSize = fileObj.size; 449 } catch (e) { 450 return "error"; 451 } 452 } 453 fileSize = ((fileSize / 1024) + "").split(".")[0]; 454 return fileSize; 455 } 456 };
然后新建一个一般预处理文件或者页面,都可以。以上面的“UploadPersonImage.ashx”为例,代码如下:
1 /// <summary> 2 /// UploadPersonImage 的摘要说明 3 /// </summary> 4 public class UploadPersonImage : IHttpHandler 5 { 6 7 public void ProcessRequest(HttpContext context) 8 { 9 var x = context.Request.Params["x1"]; //水平偏移量 10 var y = context.Request.Params["y1"]; //垂直偏移量 11 var x2 = context.Request.Params["x2"]; //水平偏移量 + 截取宽度 12 var y2 = context.Request.Params["y2"]; //垂直偏移量 + 截取高度 13 var w = context.Request.Params["w"]; //截取宽度 14 var h = context.Request.Params["h"]; //截取高度 15 var maxW = context.Request.Params["maxW"];//客户端截取时,图片的最大宽度 16 var maxH = context.Request.Params["maxH"];//客户端截取时,图片的最大高度 17 18 if (string.IsNullOrEmpty(x) || string.IsNullOrEmpty(y) || string.IsNullOrEmpty(w) || string.IsNullOrEmpty(h) || string.IsNullOrEmpty(maxW) || string.IsNullOrEmpty(maxH)) 19 { 20 context.Response.Write("false"); 21 return; 22 } 23 24 HttpFileCollection files = context.Request.Files; 25 if (files == null || files.Count <= 0) 26 { 27 context.Response.Write("false"); 28 return; 29 } 30 // 服务器端存储文件的文件夹(磁盘路径) 31 string path = context.Server.MapPath("/"); 32 const string imgpath = "WeixinPage/uploadImg"; //保存地址 33 if (Directory.Exists(path + imgpath) == false) 34 { 35 //如果不存在就创建file文件夹 36 Directory.CreateDirectory(path + imgpath); 37 } 38 39 var fileName = string.Empty; 40 for (var i = 0; i < files.Count; i++) 41 { 42 //首先将图片缩放到与客户端截取时的大小一致 43 using (var bitmap = GenerateThumbnail(int.Parse(maxW), int.Parse(maxH), files[i].InputStream)) 44 { 45 fileName = "/" + DateTime.Now.Ticks + ".jpg"; 46 var newFileName = path + imgpath + fileName; 47 try 48 { 49 //开始截取 50 ImageCropper(bitmap, int.Parse(w), int.Parse(h), int.Parse(x), int.Parse(y), newFileName, 51 System.Drawing.Imaging.ImageFormat.Jpeg); 52 } 53 catch (Exception ex) 54 { 55 context.Response.Write("false"); 56 return; 57 } 58 } 59 } 60 61 //上传成功,输出图片相对路径 62 context.Response.Write("../uploadImg" + fileName); 63 64 //上传失败 65 context.Response.Flush(); 66 } 67 68 /// <summary> 69 /// 生成指定大小的图片 70 /// </summary> 71 /// <param name="maxWidth">生成图片的最大宽度</param> 72 /// <param name="maxHeight">生成图片的最大高度</param> 73 /// <param name="imgFileStream">图片文件流对象</param> 74 private System.Drawing.Bitmap GenerateThumbnail(int maxWidth, int maxHeight, System.IO.Stream imgFileStream) 75 { 76 using (var img = System.Drawing.Image.FromStream(imgFileStream)) 77 { 78 var sourceWidth = img.Width; 79 var sourceHeight = img.Height; 80 81 var thumbWidth = sourceWidth; //要生成的图片的宽度 82 var thumbHeight = sourceHeight; //要生成图片的的高度 83 84 //计算生成图片的高度和宽度 85 if (sourceWidth > maxWidth || sourceHeight > maxHeight) 86 { 87 var rateWidth = (double)sourceWidth / maxWidth; 88 var rateHeight = (double)sourceHeight / maxHeight; 89 90 if (rateWidth > rateHeight) 91 { 92 thumbWidth = maxWidth; 93 thumbHeight = (int)Math.Round(sourceHeight / rateWidth); 94 } 95 else 96 { 97 thumbWidth = (int)Math.Round(sourceWidth / rateHeight); 98 thumbHeight = maxHeight; 99 } 100 } 101 102 var bmp = new System.Drawing.Bitmap(thumbWidth, thumbHeight); 103 //从Bitmap创建一个System.Drawing.Graphics对象,用来绘制高质量的缩小图。 104 using (var gr = System.Drawing.Graphics.FromImage(bmp)) 105 { 106 //设置 System.Drawing.Graphics对象的SmoothingMode属性为HighQuality 107 gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 108 //下面这个也设成高质量 109 gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 110 //下面这个设成High 111 gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; 112 113 //把原始图像绘制成上面所设置宽高的缩小图 114 var rectDestination = new System.Drawing.Rectangle(0, 0, thumbWidth, thumbHeight); 115 gr.DrawImage(img, rectDestination, 0, 0, sourceWidth, sourceHeight, 116 System.Drawing.GraphicsUnit.Pixel); 117 return bmp; 118 } 119 } 120 } 121 /// <summary> 122 /// 截取图片中的一部分 123 /// </summary> 124 /// <param name="img">待截取的图片</param> 125 /// <param name="cropperWidth">截取图片的宽</param> 126 /// <param name="cropperHeight">截取图片的高</param> 127 /// <param name="offsetX">水平偏移量</param> 128 /// <param name="offsetY">垂直偏移量</param> 129 /// <param name="savePath">截取后的图片保存位置</param> 130 /// <param name="imgFormat">截取后的图片保存格式</param> 131 private void ImageCropper(System.Drawing.Image img, int cropperWidth, int cropperHeight, int offsetX, 132 int offsetY, string savePath, 133 System.Drawing.Imaging.ImageFormat imgFormat) 134 { 135 using (var bmp = new System.Drawing.Bitmap(cropperWidth, cropperHeight)) 136 { 137 //从Bitmap创建一个System.Drawing.Graphics对象,用来绘制高质量的缩小图。 138 using (var gr = System.Drawing.Graphics.FromImage(bmp)) 139 { 140 //设置 System.Drawing.Graphics对象的SmoothingMode属性为HighQuality 141 gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 142 //下面这个也设成高质量 143 gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 144 //下面这个设成High 145 gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; 146 147 //把原始图像绘制成上面所设置宽高的截取图 148 var rectDestination = new System.Drawing.Rectangle(offsetX, offsetY, cropperWidth, cropperHeight); 149 gr.DrawImage(img, 0, 0, rectDestination, 150 System.Drawing.GraphicsUnit.Pixel); 151 152 //保存截取的图片 153 bmp.Save(savePath, imgFormat); 154 } 155 } 156 } 157 158 public bool IsReusable 159 { 160 get 161 { 162 return false; 163 } 164 } 165 }
以上算是基本实现了,下面给出相应的效果图。
Jcrop插件的下载地址:http://code.ciaoca.com/jquery/jcrop/
参考博客文章链接地址:http://blog.csdn.net/sq111433/article/details/17562703
标签:
原文地址:http://www.cnblogs.com/jokeny-gyh/p/5789518.html