基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)


Posted in Javascript onSeptember 02, 2011

正文:
为了使层次分明及便于阅读,  整个解决方案如下:
基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)

其中BitmapCutter.Core是图片的服务器端处理程序, 类图为:

基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS) 

简单说明下, 更多说明可查看源码注释 :

Cutter为裁剪对象, 用于存储客户端通过AJAX提交的数据.

Helper为图片处理类, 包括图片翻转(RotateImage()), 图片裁剪(GenerateBitmap()).

Callback为服务器端图片处理类, 通过使用Cutter封装客户端AJAX提交的数据, 然后调用Helper中的方法来完成图片处理.

BitmapScissors是一个HttpHandler, 通过客户端返回的 'action' 来调用Callback中的方法:

基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)
注: 此处用了反射来根据'action'值动态调用Callback中的方法, 如不习惯或认为不妥的请自行更改...

客户端AJAX提交的Url为"scissors.axd", 实际为BitmapScissors类(如修改了服务器端处理程序, 请在Web.config中根据实际进行httpHandler节点配置), 本例为:

基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)

Ok, 下面开始介绍重点, $.fn.bitmapcutter插件的实现:

先来上张效果图,标记下bitmapcutter中的Dom对象, 额, 喜欢刚大木的漫迷比较多, 就来张洛克昂的吧:

基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)

说明: 

holder为原图承载容器, 当原图过大时可只显示部分, 通过平移来查看未显示区域的图象, holder为div, 设置position样式为relative, 这样原图img(同为img对象)的position样式为absolute时, 即可通过控制其left, top 值来进行图片的平移显示, 注意holder的overflow必须设置成hidden, 这样img将会被包裹在holder中,超出holder边界的img将会被隐藏.

cutter为截取框, 可进行拖拽以选择自己敢兴趣的截取区域, 拖拽区域在holder容器内,  同时会在thumbimg(原理与holder+img相同)内生成缩略图.

opts - 功能区域, 提供所有可用的功能按钮, 包括: 放大, 缩小, 左移, 右移, 上移, 下移, 还原, 左旋转, 右旋转.

info - 图片相素, 用于显示当前待截取图片的宽高比.

原理:

熟悉css的话应该很容易看出来, 利用相对定位的灵活性和js对css的控制.

插件说明:

由于插件的代码比较多, 这里就拣重点的讲了:

1. 全局变量:

基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)

  由于在整个裁剪过程中会频繁的使用一些数据和jQuery对象, 所以定义了一个全局变量用来存储.

  $originalSize: 原图的相素, 在首次加载原图时获取, 不可改变, 主要是为放大, 缩小和还原提供一对基础数据(长,宽). 
  $zoomValue: 当前缩放比, 在执行放大或缩小时同步.
  $thumbimg: 裁剪区域缩略图的jQuery对象, 在该dom被创建时赋值.
  $img: 原图jQuery对象, 在该dom被创建时获取.
  $cutter: 裁剪区域, 同样在dom被创建时获取.

2. 插件:

  为了方便图象的控制, 同样编写了几个附加插件, 如果同学们在使用中有重名的请设法避免 ;-)

  $.fn.f: 用于获取jQuery对象的样式值, 例如width, height, left, top等.
  $.fn.loadBitmap: 用于预载入图片以获取正确的相素.
  $.fn.scaleBitmap: 用于缩放图片..缩放比率来自全局变量$zoomValue.
  $.fn.dragndrop: 我的上一个插件$.fn.Drags的定制版, 主要是为了实现某一dom对象在特定元素内的拖拽.

3. API:

  $.fn.bitmapCutter的API包括:

  src(String): 待裁剪图片的路径(相对于程序主目录), 默认为空, 必须,
  renderTo(String(Selector)|jQuery Object): bitmapCutter插件容器, jQuery对象或选择器, 默认为$(document.body),
  holderSize(Object): holder对象的大小, 包括width和height两个值, 默认为{ width: 300, height: 400 },
  cutterSize(Object): cutter对象的大小(生成头像大小), 包括width和height两个值, 默认为{ width: 70, height: 70 },
  zoomStep(Float): 每次缩放的比率更改幅度, 默认为0.2,
  zoomIn(Float): 放大时与原图的最大比, 默认为2.0,
  zoomOut(Float): 缩小时于原图的最大比, 默认为0.1,
  rotateAngle(Int): 图片翻转角度, 可取值为 90, 180, -90, -180, 默认为 90,
  moveStep(Int): 原图平移时的平移象素, 默认为100,
  onGenerated(Function): 成功生成头像时触发事件数, bitmapCutter向此方法传递一个参数 'src', 表示新裁剪生成的头像路径. 此属性的默认值为 function(src) { },
  lang(Object): 功能区域各按钮的Tooltip, lang的API为:

                zoomout(String): 放大, 默认值 'Zoom out',
                zoomin(String): 缩小, 默认值'Zoom in',
                original(String): 原始大小, 默认值'Original size',
                clockwise(String): 顺时针旋转, 默认值'Clockwise rotation({0} degrees)', 需包含 {0} 以便格式化时使用rotateAngle值填充,
                counterclockwise(String): 逆时针旋转, 默认值'Counterclockwise rotation({0} degrees)', 需包含 {0} 以便格式化时使用rotateAngle值填充,
                generate(String): 生成头像, 默认值'Generate!',
                process(String): 生成头像时的提示语, 默认值为'Please wait, transaction is processing......',
                left(String): 左平移, 默认值'Left',
                right(String): 右平移, 默认值'Right',
                up(String): 上移, 默认值'Up',
                down(String): 下移, 默认值'Down'

   API原型为:

   基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS) 

4. 开发技巧:

   为了便于代码管理及功能优化, 将功能进行了归纳, 大致可分为:

   缩放(zoom): 细分为放大和缩小, 
   翻转(rotate): 细分为顺时针和逆时针, 
   移动(move): 细分为上|右|下|左平移.

   所以直接编写三个 '基类' (具体实现看源码):
   izoom(zv): 提供图片放大或缩小功能, zv为当前缩放比,
   irotate(angle): 提供图片旋转功能, angle为当前旋转角度,
   imove(direction): 提供原图平移功能, direction为移动方向, 包括'left','up','right','down'.

   那么现在需要的就是细分各个功能:
   基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)
   这里我使用了一个对象scissors来封装这些操作, 使用call来 '继承', 当然你也可以使用 '冒充' 或者 '原型链' 这些手段来实现. 这样的话在绑定这些方法的时候使用eval和json就可以很轻松的完成:
   基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)
   看不明白?那么贴上Html树呢?
   基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)

5. 自问自答

  Q: 为什么要在服务器端来实现旋转效果?
  A: 为了实现大众化和浏览器兼容, 所以我放弃了滤镜和Canvas.

  Q: Photoshop等图片处理软件在裁剪时都是实现反相效果的, 为什么不实现?
  A: 我想一个程序兼顾UI的时候也要考虑效率, 如果实现反相的话, cutter对象内同样需要内置一个img来与thumbimg同步, 那么当旋转图象时内存的累积是非常恐怖的.

  Q: 相比Flash, Siverlight而言这么一个东西有什么好处?
  A: 额, 其实我最初是打算用Flash做的, 不过考虑到大众化的问题(多少.Net开发人员会as?), jQuery+HttpHandler是一个不错的选择, 开放的API, 开放的源码, 我想远比让大家去改一个.fla来的轻松愉快.

  Q: 那么坏处?
  A: 大家都知道, 浏览器的缓存是把双刃剑, 在bitmapCutter里他就很烦人, 为了实现图片旋转后刷新, 只能为img的src加上一个戳(随机数?时间?whatever..), 但是这样会带来一个必然的结果 - 浏览器内存累积(目前已将此威胁降至最低 ;-)),   额..!@#$%

6. 注

  未对gif类型图片作特殊处理, 所以仅会取回第一桢处理, 生成头像格式为Png, 如果需要的话自己修改源码.
  jquery.bitmapcutter.js 尾部方法为模拟  c# string.format, 必须的.
  支持键盘操作, 方向键控制平移, +-控制放大缩小, 不喜可从源码删除.

7. demo中的简单示例

  使用一张C.C的图来截取头像, 设置截取框长宽为120:120, 容器为id为container的div, 每次旋转角度为90, 顺时针旋转功能按钮的提示为 '顺时针旋转{0}度.'
  基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)
  效果:
  基于jQuery+HttpHandler实现图片裁剪效果代码(适用于论坛, SNS)

8. 源码包(测试图片多):

/201109/yuanma/BitmapCutter_3water.rar
Javascript 相关文章推荐
JS Pro-深入面向对象的程序设计之继承的详解
May 07 Javascript
js函数排序的实例代码
Jul 01 Javascript
jquery mobile页面跳转后样式丢失js失效的解决方法
Sep 06 Javascript
非常实用的12个jquery代码片段
Nov 02 Javascript
JS实现根据用户输入分钟进行倒计时功能
Nov 14 Javascript
通过学习bootstrop导航条学会修改bootstrop颜色基调
Jun 11 Javascript
详解AngularJS ng-class样式切换
Jun 27 Javascript
详解React-Native解决键盘遮挡问题(Keyboard遮挡问题)
Jul 13 Javascript
layui默认选中table的CheckBox复选框方法
Sep 19 Javascript
原生javascript中this几种常见用法总结
Feb 24 Javascript
package.json各个属性说明详解
Mar 11 Javascript
JavaScript 链表定义与使用方法示例
Apr 28 Javascript
基于jquery的loading 加载提示效果实现代码
Sep 01 #Javascript
jQuery1.6 类型判断实现代码
Sep 01 #Javascript
jquery 简短几句代码实现给元素动态添加及获取提示信息
Sep 01 #Javascript
用javascript作一个通用向导说明
Aug 30 #Javascript
JS 无限级 Select效果实现代码(json格式)
Aug 30 #Javascript
javascript 原型继承介绍
Aug 30 #Javascript
dojo学习第二天 ajax异步请求之绑定列表
Aug 29 #Javascript
You might like
php新浪微博登录接口用法实例
2014/12/23 PHP
PHP实现的注册,登录及查询用户资料功能API接口示例
2017/06/06 PHP
JavaScript While 循环基础教程
2007/04/05 Javascript
javascript jQuery $.post $.ajax用法
2008/07/09 Javascript
基于jquery实现的表格分页实现代码
2011/06/21 Javascript
一些有用的JavaScript和jQuery的片段分享
2011/08/23 Javascript
JS中 用户登录系统的解决办法
2013/04/15 Javascript
javascript中for/in循环及使用技巧
2015/09/01 Javascript
用JS生成UUID的方法实例
2016/03/30 Javascript
创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件
2016/06/02 Javascript
Javascript中的迭代、归并方法详解
2016/06/14 Javascript
AngularJS基础 ng-class-odd 指令示例
2016/08/01 Javascript
12个非常有用的JavaScript技巧
2017/05/17 Javascript
vue实现评论列表功能
2019/10/25 Javascript
es6中Promise 对象基本功能与用法实例分析
2020/02/23 Javascript
vue自定义树状结构图的实现方法
2020/10/18 Javascript
Python中跳台阶、变态跳台阶与矩形覆盖问题的解决方法
2018/05/19 Python
Django rest framework工具包简单用法示例
2018/07/20 Python
python项目对接钉钉SDK的实现
2019/07/15 Python
python实现串口通信的示例代码
2020/02/10 Python
Python使用configparser读取ini配置文件
2020/05/25 Python
python3 re返回形式总结
2020/11/20 Python
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
详解HTML5中download属性的应用
2015/08/06 HTML / CSS
PHP面试题附答案
2015/11/28 面试题
电厂厂长岗位职责
2014/01/02 职场文书
保险经纪人求职信
2014/03/11 职场文书
食品安全汇报材料
2014/08/18 职场文书
贫困证明书格式及范文
2014/10/15 职场文书
2014年秘书工作总结
2014/11/25 职场文书
博物馆观后感
2015/06/05 职场文书
小学运动会加油词
2015/07/18 职场文书
一年级语文教学随笔
2015/08/14 职场文书
外出学习心得体会范文
2016/01/18 职场文书
Golang 切片(Slice)实现增删改查
2022/04/22 Golang
Window server 2012 R2 AD域的组策略相关设置
2022/04/28 Servers