(此教程包括前端实现图片裁剪,后端进行获取裁剪区并保存)
最近有一个需求,微信公众号上传图片,支持自定义裁剪。
以前用过一款裁剪插件cropper,很久没用了,不知道对移动端操作兼容如何,重新从网上搜索更合适的插件
首先试过PhotoClip,这个插件裁剪区域是固定的,不能自定义缩放(也许需求太匆忙没有研究透,亦或者可以修改原文件优化这一点),对于用户体验不够好,故,放弃
然后又遇到一款插件---Jcrop,完美符合需求,项目结合百度插件 WebUploader上传获取原图,可适配移动端选取相册/拍照上传,获取到选择的照片设置给Jcrop(jcrop.setImage(response.url);)进行裁剪
Jcrop优势:
- 对所有图片均unobtrusively(无侵入的,保持DOM简洁)
- 支持宽高比例锁定
- 支持 minSize/maxSize设置
- 支持改变选区或移 动选区时的回调(Callback)
- 支持用键盘微调选区
- 通过API创建互动,比如动画效果
- 支持CSS样式
- 简单便捷,js和css通俗易懂,便于维护
Jcrop实现非常简答, 有兴趣继续看下文:
1、引用js文件和css文件:
<script type="text/javascript" src="@(WeixinConfig.ResourceAddress)js/jcrop/jquery.Jcrop.js"></script>
<script type="text/javascript" src="@(WeixinConfig.ResourceAddress)js/jcrop/jquery.color.js"></script>
<link rel="stylesheet" href="@(WeixinConfig.ResourceAddress)js/jcrop/jquery.Jcrop.css">
2、定义裁剪DOM,仅需要一个Img标签
<div id="jcropBox" style="width: 100%; height: 90%;">
<!-- This is the image we‘re attaching Jcrop to -->
<img src="" id="jcropTarget" />
</div>
3、初始化Jcrop
// 默认参数初始化Jcrop $("#jcropTarget").Jcrop();
仅需上面三个步骤,就能完成一个支持移动、缩放、拖放的图片裁剪
也可以自定义初始化Jcrop的展现形式
$(‘#jcropTarget‘).Jcrop({ onChange: showCoords, onSelect: showCoords, onRelease: clearCoords, boxWidth: jcropW, boxHeight: jcropH, handleSize: isMobile() === 0 ? 28 : 15 }, function () { jcrop = this; jcrop.setSelect([130, 65, 130 + 350, 65 + 285]); jcrop.setOptions({ bgFade: true, bgOpacity: 0.5, bgColor: ‘black‘, addClass: ‘jcrop-light‘, handleOffset: 20 }); });
文章最后有各参数说明表格,此处不做一一解释
function showCoords(c) { x = c.x; y = c.y; w = c.w; h = c.h; }; function clearCoords() { $(‘#coords input‘).val(‘‘); };
进一步对图片进行保存,我采取的是获取裁剪图片的x,y,width,height
添加一个裁剪按钮
<button id="btnSaveJcropImg" class="btnJcrop">裁剪</button>
注册click事件,把最终裁剪的x,y,w,h参数传给后端,进行分析保存
/// <summary> /// 保存裁剪后的新图片(通过x,y,w,h对原图进行截取) /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="w"></param> /// <param name="h"></param> /// <param name="fileName">文件名,WebUploader上传到服务器的原图</param> /// <returns></returns> [HttpPost] public JsonResult JcropUploadProcess(int x, int y, int w, int h, string fileName) { try { ViewBag.YearEndUploadUrl = yearEndUploadUrl; //保存到临时文件夹 string path = "/upload/yearend/"; string localPath = HttpContext.Server.MapPath(path); if (!System.IO.Directory.Exists(localPath)) { System.IO.Directory.CreateDirectory(localPath); } localPath = HttpContext.Server.MapPath(path + "/temp"); if (!System.IO.Directory.Exists(localPath)) { System.IO.Directory.CreateDirectory(localPath); } // 图片路径 string oldPath = System.IO.Path.Combine(localPath, fileName); // 新图片路径 string newPath = System.IO.Path.GetExtension(oldPath); newPath = oldPath.Substring(0, oldPath.Length - newPath.Length) + "_new" + newPath; //定义截取矩形 System.Drawing.Rectangle cropArea = new System.Drawing.Rectangle(x, y, w, h); //要截取的区域大小 //加载图片 System.Drawing.Image img = System.Drawing.Image.FromStream(new System.IO.MemoryStream(System.IO.File.ReadAllBytes(oldPath))); //定义Bitmap对象 System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(img); //进行裁剪 System.Drawing.Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat); //保存成新文件 bmpCrop.Save(newPath); //释放对象 img.Dispose(); bmpCrop.Dispose(); //获取文件名+后缀 string filePathName = System.IO.Path.GetFileName(newPath); return Json(new { ret = 0, jsonrpc = "2.0", id = "id", filePath = filePathName, url = yearEndUploadUrl + "temp/" + filePathName }); } catch (Exception ex) { return Json(new { ret = 1, jsonrpc = 2.0, error = new { code = 102, message = ex.Message }, id = "id" }); } }
最后附上扩展说明
Options参数说明
| 参数名 | 默认值 | 参数说明 |
| allowSelect | true | 允许新选框 |
| allowMove | true | 允许选框移动 |
| allowResize | true | 允许选框缩放 |
| trackDocument | true | |
| baseClass | "jcrop" | 基础样式名前缀。说明:class="jcrop-holder",更改的只是其中的 jcrop。 |
| addClass | null | 添加样式。假设class名为 "test",则添加样式后为class="test jcrop-holder" |
| bgColor | "black" | 背景颜色。颜色关键字、HEX、RGB 均可。 |
| bgOpacity | 0.6 | 背景透明度 |
| bgFade | false | 是否使用背景过渡效果 |
| borderOpacity | 0.4 | 选框边框透明度 |
| handleOpacity | 0.5 | 缩放按钮透明度 |
| handleSize | 9 | 缩放按钮大小 |
| handleOffset | 5 | 缩放按钮与边框的距离 |
| aspectRatio | 0 | 选框宽高比。说明:width/height |
| keySupport | true | 支持键盘控制。按键列表:上下左右(移动)、Esc(取消)、Tab(跳出裁剪框,到下一个) |
| cornerHandles | true | 允许边角缩放 |
| sideHandles | true | 允许四边缩放 |
| drawBorders | true | 绘制边框 |
| dragEdges | true | 允许拖动边框 |
| fixedSupport | true | |
| touchSupport | null | |
| boxWidth | 0 | 画布宽度 |
| boxHeight | 0 | 画布高度 |
| boundary | 2 | 边界。说明:可以从边界开始拖动鼠标选择裁剪区域 |
| fadeTime | 400 | 过度效果的时间 |
| animationDelay | 20 | 动画延迟 |
| swingSpeed | 3 | 过渡速度 |
| minSelect | [0,0] | 选框最小选择尺寸。说明:若选框小于该尺寸,则自动取消选择 |
| maxSize | [0,0] | 选框最大尺寸 |
| minSize | [0,0] | 选框最小尺寸 |
| onChange | function(){} | 选框改变时的事件 |
| onSelect | function(){} | 选框选定时的事件 |
| onRelease | function(){} | 取消选框时的事件 |
API方法说明
| 方法 | 方法的使用说明 |
| setImage(string) | 设定(或改变)图像。例:jcrop_api.setImage("newpic.jpg") |
| setOptions(object) | 设定(或改变)参数,格式与初始化设置参数一样 |
| setSelect(array) | 创建选框,参数格式为:[x,y,x2,y2] |
| animateTo(array) | 用动画效果创建选框,参数格式为:[x,y,x2,y2] |
| release() | 取消选框 |
| disable() | 禁用 Jcrop。说明:已有选框不会被清除。 |
| enable() | 启用 Jcrop |
| destroy() | 移除 Jcrop |
| tellSelect() | 获取选框的值(实际尺寸)。例子:console.log(jcrop_api.tellSelect()) |
| tellScaled() | 获取选框的值(界面尺寸)。例子:console.log(jcrop_api.tellScaled()) |
| getBounds() | 获取图片实际尺寸,格式为:[w,h] |
| getWidgetSize() | 获取图片显示尺寸,格式为:[w,h] |
| getScaleFactor() | 获取图片缩放的比例,格式为:[w,h] |
jQuery Jcrop插件下载(其中css文件有部分优化)