基于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 相关文章推荐
JQuery浮动DIV提示信息并自动隐藏的代码
Aug 29 Javascript
按下回车键指向下一个位置的一个函数代码
Mar 10 Javascript
javascript轻量级模板引擎juicer使用指南
Jun 22 Javascript
基于jQuery实现select下拉选择可输入附源码下载
Feb 03 Javascript
JQuery解析XML数据的几个简单实例
May 18 Javascript
初学者AngularJS的环境搭建过程
Oct 27 Javascript
chorme 浏览器记住密码后input黄色背景处理方法(两种)
Nov 22 Javascript
javascript、php关键字搜索函数的使用方法
May 29 Javascript
Vue创建头部组件示例代码详解
Oct 23 Javascript
JavaScript实现学生在线做题计时器功能
Dec 05 Javascript
优化Vue中date format的性能详解
Jan 13 Javascript
JavaScript实现省市区三级联动
Feb 13 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笔记之:数据类型与常量的使用分析
2013/05/14 PHP
PHP7常量数组用法分析
2016/09/26 PHP
php array_pop 删除数组最后一个元素实例
2016/11/02 PHP
PHP里的$_GET数组介绍
2019/03/22 PHP
修改Laravel自带的认证系统的User类的命名空间的步骤
2019/10/15 PHP
jquery 简单导航实现代码
2009/09/11 Javascript
jquery 简单图片导航插件jquery.imgNav.js
2010/03/17 Javascript
jQuery asp.net 用json格式返回自定义对象
2010/04/07 Javascript
JS 控制小数位数的实现代码
2011/08/02 Javascript
详解jquery中$.ajax方法提交表单
2014/11/03 Javascript
jQuery中$(function() {});问题详解
2015/08/10 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
2015/09/02 Javascript
javascript实现tab切换的四种方法
2015/11/05 Javascript
一系列Bootstrap导航条使用方法分享
2016/04/29 Javascript
浅谈$('div a') 与$('div>a')的区别
2016/07/18 Javascript
jQuery实现可拖拽3D万花筒旋转特效
2017/01/03 Javascript
vuejs2.0运用原生js实现简单的拖拽元素功能示例
2017/02/24 Javascript
jquery.validate.js 多个相同name的处理方式
2017/07/10 jQuery
Angular中自定义Debounce Click指令防止重复点击
2017/07/26 Javascript
JQuery实现table中tr上移下移的示例(超简单)
2018/01/08 jQuery
如何在 JavaScript 中更好地利用数组
2018/09/27 Javascript
微信小程序纯文本实现@功能
2020/04/08 Javascript
基于python的汉字转GBK码实现代码
2012/02/19 Python
python中使用mysql数据库详细介绍
2015/03/27 Python
浅谈Python 的枚举 Enum
2017/06/12 Python
Python帮你识破双11的套路
2019/11/11 Python
Python 词典(Dict) 加载与保存示例
2019/12/06 Python
面向新手解析python Beautiful Soup基本用法
2020/07/11 Python
Python实现图片指定位置加图片水印(附Pyinstaller打包exe)
2021/03/04 Python
使用placeholder属性设置input文本框的提示信息
2020/02/19 HTML / CSS
军训教官感言
2014/03/02 职场文书
中秋晚会策划方案
2014/06/12 职场文书
三月雷锋月活动总结
2014/07/03 职场文书
2015年度质量工作总结报告
2015/04/27 职场文书
反邪教教育心得体会
2016/01/15 职场文书
PHP实现考试倒计时功能代码
2021/04/16 PHP