基于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 date对象的减法处理实现代码
Dec 28 Javascript
ajax中get和post的说明及使用与区别
Dec 23 Javascript
如何从jQuery的ajax请求中删除X-Requested-With
Dec 11 Javascript
js charAt的使用示例
Feb 18 Javascript
javascript设计模式之中介者模式Mediator
Dec 30 Javascript
详解JavaScript 中的 replace 方法
Jan 01 Javascript
javascript小数精度丢失的完美解决方法
May 31 Javascript
底部悬浮通栏可以关闭广告位的实现方法
Jun 01 Javascript
Vue源码学习之初始化模块init.js解析
Nov 02 Javascript
weebox弹出窗口不居中显示的解决方法
Nov 27 Javascript
快速解决处理后台返回json数据格式的问题
Aug 07 Javascript
vue 实现Web端的定位功能 获取经纬度
Aug 08 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
世界收音机发展史
2021/03/01 无线电
Gregarius中文日期格式问题解决办法
2008/04/22 PHP
WordPress后台中实现图片上传功能的实例讲解
2016/01/11 PHP
php获取开始与结束日期之间所有日期的方法
2016/11/29 PHP
Web前端设计模式  制作漂亮的弹出层
2010/10/29 Javascript
jQuery 源码分析笔记(3) Deferred机制
2011/06/19 Javascript
document.getElementById介绍
2011/09/13 Javascript
javascript-简单的计算器实现步骤分解(附图)
2013/05/30 Javascript
javascript常见操作汇总
2014/09/03 Javascript
原生js配合cookie制作保存路径的拖拽
2015/12/29 Javascript
JS简单实现String转Date的方法
2016/03/02 Javascript
最全的Javascript编码规范(推荐)
2016/06/22 Javascript
分享一个原生的JavaScript拖动方法
2016/09/25 Javascript
微信小程序 本地存储及登录页面处理实例详解
2017/01/11 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
react native 获取地理位置的方法示例
2018/08/28 Javascript
node上的redis调用优化示例详解
2018/10/30 Javascript
NodeJs实现简单的爬虫功能案例分析
2018/12/05 NodeJs
vue实现的下拉框功能示例
2019/01/29 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
2019/02/27 Javascript
小程序:授权、登录、session_key、unionId的详解
2019/05/15 Javascript
Layui table field初始化加载时进行隐藏的方法
2019/09/19 Javascript
Vue-drag-resize 拖拽缩放插件的使用(简单示例)
2019/12/04 Javascript
跟老齐学Python之print详解
2014/09/28 Python
在Python的Flask框架中使用模版的入门教程
2015/04/20 Python
Python使用BeautifulSoup库解析HTML基本使用教程
2016/03/31 Python
python引入导入自定义模块和外部文件的实例
2017/07/24 Python
使用Python监视指定目录下文件变更的方法
2018/10/15 Python
Python mutiprocessing多线程池pool操作示例
2019/01/30 Python
django认证系统 Authentication使用详解
2019/07/22 Python
pycharm编写spark程序,导入pyspark包的3中实现方法
2019/08/02 Python
python 一篇文章搞懂装饰器所有用法(建议收藏)
2019/08/23 Python
python函数声明和调用定义及原理详解
2019/12/02 Python
中英文求职信范文
2014/01/27 职场文书
2016年社区国庆节活动总结
2016/04/01 职场文书
利用Redis实现点赞功能的示例代码
2022/06/28 Redis