jquery 图片截取工具jquery.imagecropper.js


Posted in Javascript onApril 09, 2010

除了jquery,本插件还引用了UI库,包括ui.draggable.js
ImageCropper 演示需要asp.net支持。测试通过
ImageCropper 下载 https://3water.com/jiaoben/25688.html
插件用法:

var imageCropper = $('#imgBackground').imageCropper();

要注意的是此插件只应用在有src属性的img标签上。
通过插件输出的参数,即可以通过服务器端代码截取图片,比如:
$('#imgCroppedImage').attr('src', 'CropImage.ashx?p=' + imageCropper.settings.imagePath + '&z=' + imageCropper.settings.zoomLevel + '&t=' + imageCropper.settings.top + '&l=' + imageCropper.settings.left + '&w=' + imageCropper.settings.width + '&h=' + imageCropper.settings.height + '&' + Math.random());

asp.net hander CropImage.ashx:
public class CropImage : IHttpHandler 
{ 
public void ProcessRequest(HttpContext context) 
{ 
string imgPath = Convert.ToString(context.Request["p"]); 
float zoomLevel = Convert.ToSingle(context.Request["z"]); 
int top = Convert.ToInt32(context.Request["t"]); 
int left = Convert.ToInt32(context.Request["l"]); 
int width = Convert.ToInt32(context.Request["w"]); 
int height = Convert.ToInt32(context.Request["h"]); 
context.Response.ContentType = "image/jpeg"; 
Crop(HttpContext.Current.Server.MapPath(imgPath), zoomLevel, top, left, width, height).WriteTo(context.Response.OutputStream); 
} 
public MemoryStream Crop(string imgPath, float zoomLevel, int top, int left, int width, int height) 
{ 
Image img = Image.FromFile(imgPath); 
Bitmap bitmap = new Bitmap(width, height); 
Graphics g = Graphics.FromImage(bitmap); 
g.DrawImage(img, new Rectangle(0, 0, width, height), new Rectangle((int)(left / zoomLevel), (int)(top / zoomLevel), (int)(width / zoomLevel), (int)(height / zoomLevel)), GraphicsUnit.Pixel); 
MemoryStream ms = new MemoryStream(); 
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
img.Dispose(); 
g.Dispose(); 
bitmap.Dispose(); 
return ms; 
} 
public bool IsReusable 
{ 
get 
{ 
return false; 
} 
} 
}

重点是插件,因为源代码注释比较全,直接贴代码在这:
/** 
* Copyright (c) 2010 Viewercq (http://www.cnblogs.com/viewercq/archive/2010/04/04/1704093.html) 
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 
* 
* Version: 1.0 
* 
* Demo: https://dl.dropbox.com/u/4390741/ImageCropper.htm 
*/ 
; (function($) { 
$.fn.extend({ 
imageCropper: function(options) { 
if (!this.is('img') || typeof this.attr('src') == 'undefined' || this.attr('src') == '') { 
throw 'Please notice that this jquery plguin only could be applied to img and the src of img could not be null!'; 
} 
var defaults = { 
//原图路径 
imagePath: this.attr('src'), 
//缩放级别 
zoomLevel: 1, 
//图片相对于截取框是否居中 
center: false, 
//截取框与图片的相对位置 
left: 0, top: 0, 
//截取框的大小 
width: 200, height: 200, 
//工作区大小 
cropWorkAreaSize: { width: 600, height: 400 }, 
//截取框相对于工作区的位置 
cropFrameRect: { center: true, top: 0, left: 0 }, 
//缩放范围 
zoom: { min: 0, max: 2, step: 0.01 }, 
//回调函数 
callbacks: { 
//移动图片后 
dragging: false, 
//缩放后 
zoomed: false 
} 
}; 
if (options) { 
defaults = $.extend(defaults, options); 
} 
return new imageCropper(this, defaults); 
} 
}); 
function imageCropper(image, settings) { 
this.init(image, settings); 
}; 
imageCropper.prototype = { 
settings: false, 
wrapper: $('<div class="image-cropper-wrapper"/>'), 
zoomWrapper: $('<div class="zoom-wrapper"><div class="zoom-out-button"/><div class="zoom-scrollbar"><div class="zoom-scroller"/></div><div class="zoom-in-button"/></div>'), 
img: false, 
init: function(image, settings) { 
var context = this; 
this.settings = settings; 
image.addClass('background-img'); 
//生成html 
image.wrap(this.wrapper).wrap('<div class="crop-work-area"/>').wrap('<div class="crop-background"/>'); 
this.wrapper = $('.image-cropper-wrapper'); 
$('.crop-work-area', this.wrapper).append('<div class="crop-frame"><img class="foreground-img" src="" /></div><div class="drag-containment"/>'); 
this.wrapper.append(this.zoomWrapper); 
$('.image-cropper-wrapper', this.wrapper).disableSelection(); 
this.reset(); 
//图片的拖动 
$('.crop-background', this.wrapper).draggable({ 
containment: $('.drag-containment', this.wrapper), 
cursor: 'move', 
drag: function(event, ui) { 
var self = $(this).data('draggable'); 
//同时移动前景图 
$('.foreground-img', this.wrapper).css({ 
left: (parseInt(self.position.left) - context.settings.cropFrameRect.left - 1) + 'px', 
top: (parseInt(self.position.top) - context.settings.cropFrameRect.top - 1) + 'px' 
}); 
//得到截图左上点坐标 
context.settings.left = context.settings.cropFrameRect.left - parseInt($(this).css('left')); 
context.settings.top = context.settings.cropFrameRect.top - parseInt($(this).css('top')); 
//移动图片的callback 
context.fireCallback(context.settings.callbacks.dragging); 
} 
}); 
$('.foreground-img', this.wrapper).draggable({ 
containment: $('.drag-containment', this.wrapper), 
cursor: 'move', 
drag: function(event, ui) { 
var self = $(this).data('draggable'); 
//同时移动背景 
$('.crop-background', this.wrapper).css({ 
left: (parseInt(self.position.left) + context.settings.cropFrameRect.left + 1) + 'px', 
top: (parseInt(self.position.top) + context.settings.cropFrameRect.top + 1) + 'px' 
}); 
//得到截图左上点坐标 
context.settings.left = context.settings.cropFrameRect.left - parseInt($('.crop-background', this.wrapper).css('left')); 
context.settings.top = context.settings.cropFrameRect.top - parseInt($('.crop-background', this.wrapper).css('top')); 
//移动图片的callback 
context.fireCallback(context.settings.callbacks.dragging); 
} 
}); 
//点击缩放 
$('.zoom-out-button,.zoom-in-button', this.wrapper).click(function() { 
var step = $(this).hasClass('zoom-in-button') ? context.settings.zoom.step : -context.settings.zoom.step; 
var tempZoomLevel = context.formatNumber(context.settings.zoomLevel + step, 3); 
//如果缩放级别超出范围 或者 缩放导致图片右下角没在截取框内 则取消缩放 
if (context.settings.zoomLevel >= context.settings.zoom.min 
&& context.settings.zoomLevel <= context.settings.zoom.max 
&& parseInt($('.crop-background', this.wrapper).css('left')) + tempZoomLevel * context.img.width > context.settings.cropFrameRect.left + context.settings.width 
&& parseInt($('.crop-background', this.wrapper).css('top')) + tempZoomLevel * context.img.height > context.settings.cropFrameRect.top + context.settings.height 
) { 
context.settings.zoomLevel = tempZoomLevel; 
context.zoom(context.img.width * context.settings.zoomLevel, context.img.height * context.settings.zoomLevel); 
$('.zoom-scroller', this.wrapper).css('left', context.settings.zoomLevel * 200 / (context.settings.zoom.max - context.settings.zoom.min) + 'px'); 
} 
context.fireCallback(context.settings.callbacks.zoomed); 
}); 
//滚动条缩放 
var cancelZoomScroll = false; 
$('.zoom-scroller', this.wrapper).draggable({ 
containment: $('.zoom-scrollbar', this.wrapper), 
axis: 'x', 
drag: function(event, ui) { 
var tempZoomLevel = (context.settings.zoom.max - context.settings.zoom.min) * parseInt($(this).css('left')) / 200; 
//如果缩放级别超出范围 或者 缩放导致图片右下角没在截取框内 则取消缩放 
if (parseInt($('.crop-background', this.wrapper).css('left')) + tempZoomLevel * context.img.width > context.settings.cropFrameRect.left + context.settings.width 
&& parseInt($('.crop-background', this.wrapper).css('top')) + tempZoomLevel * context.img.height > context.settings.cropFrameRect.top + context.settings.height 
) { 
context.settings.zoomLevel = tempZoomLevel; 
context.zoom(context.img.width * context.settings.zoomLevel, context.img.height * context.settings.zoomLevel); 
cancelZoomScroll = false; 
context.fireCallback(context.settings.callbacks.zoomed); 
} 
else { 
cancelZoomScroll = true; 
} 
}, 
stop: function(event, ui) { 
//如果缩放级别无效 则重置滚动条的值 
if (cancelZoomScroll) { 
$('.zoom-scroller', this.wrapper).css('left', context.settings.zoomLevel * 200 / (context.settings.zoom.max - context.settings.zoom.min) + 'px'); 
} 
} 
}); 
}, 
reset: function() { 
this.img = new Image(); 
this.img.src = this.settings.imagePath; 
//截取框大于工作区,则放大工作区 
var tempSize = { 
width: Math.max(this.settings.cropWorkAreaSize.width, this.settings.width), 
height: Math.max(this.settings.cropWorkAreaSize.height, this.settings.height) 
}; 
//如果截取框在工作区中居中,则重新设置截取框的位置 
if (this.settings.cropFrameRect.center) { 
this.settings.cropFrameRect.left = (tempSize.width - this.settings.width) / 2; 
this.settings.cropFrameRect.top = (tempSize.height - this.settings.height) / 2; 
} 
//如果截取框在图片中居中,则重新设置图片与截取框的相对位置 
if (this.settings.center) { 
this.settings.left = (this.img.width * this.settings.zoomLevel - this.settings.width) / 2; 
this.settings.top = (this.img.height * this.settings.zoomLevel - this.settings.height) / 2; 
} 
this.wrapper.width(tempSize.width + 2).height(tempSize.height + 25); 
$('.foreground-img,.background-img', this.wrapper).attr('src', this.settings.imagePath); 
$('.crop-work-area', this.wrapper).width(tempSize.width).height(tempSize.height); 
$('.crop-frame', this.wrapper).css({ 
left: this.settings.cropFrameRect.left + 'px', 
top: this.settings.cropFrameRect.top + 'px', 
width: this.settings.width + 'px', 
height: this.settings.height + 'px' 
}); 
$('.foreground-img', this.wrapper).css({ 
left: (-this.settings.cropFrameRect.left - 1) + 'px', 
top: (-this.settings.cropFrameRect.top - 1) + 'px' 
}); 
$('.zoom-scroller', this.wrapper).css('left', this.settings.zoomLevel * 200 / (this.settings.zoom.max - this.settings.zoom.min) + 'px'); 
$('.crop-background', this.wrapper).css({ 
opacity: 0.3, 
left: this.settings.cropFrameRect.left - this.settings.left + 'px', 
top: this.settings.cropFrameRect.top - this.settings.top + 'px' 
}); 
$('.foreground-img', this.wrapper).css({ 
left: -this.settings.left + 'px', 
top: -this.settings.top + 'px' 
}); 
this.settings.left = this.settings.cropFrameRect.left - parseInt($('.crop-background', this.wrapper).css('left')); 
this.settings.top = this.settings.cropFrameRect.top - parseInt($('.crop-background', this.wrapper).css('top')); 
this.zoom(this.img.width * this.settings.zoomLevel, this.img.height * this.settings.zoomLevel); 
}, 
zoom: function(width, height) { 
$('.crop-background, .background-img, .foreground-img', this.wrapper).width(width).height(height); 
//调整拖动限制框 
$('.drag-containment', this.wrapper).css({ 
left: this.settings.cropFrameRect.left + this.settings.width - this.settings.zoomLevel * this.img.width + 1 + 'px', 
top: this.settings.cropFrameRect.top + this.settings.height - this.settings.zoomLevel * this.img.height + 1 + 'px', 
width: 2 * this.settings.zoomLevel * this.img.width - this.settings.width + 'px', 
height: 2 * this.settings.zoomLevel * this.img.height - this.settings.height + 'px' 
}); 
}, 
formatNumber: function(number, bit) { 
return Math.round(number * Math.pow(10, bit)) / Math.pow(10, bit); 
}, 
fireCallback: function(fn) { 
if ($.isFunction(fn)) { 
fn.call(this); 
}; 
} 
}; 
})(jQuery);
Javascript 相关文章推荐
jquery获取input表单值的代码
Apr 19 Javascript
js导出格式化的excel 实例方法
Jul 17 Javascript
纯js写的分页表格数据为json串
Feb 18 Javascript
js获取时间并实现字符串和时间戳之间的转换
Jan 05 Javascript
jQuery Ajax中的事件详细介绍
Apr 16 Javascript
js查看一个函数的执行时间实例代码
Sep 12 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
Mar 04 Javascript
整理关于Bootstrap导航的慕课笔记
Mar 29 Javascript
深入学习JavaScript 高阶函数
Jun 11 Javascript
vue使用swiper.js重叠轮播组建样式
Nov 14 Javascript
微信小程序自定义tabBar的踩坑实践记录
Nov 06 Javascript
vue中利用three.js实现全景图的完整示例
Dec 07 Vue.js
跟着JQuery API学Jquery 之三 筛选
Apr 09 #Javascript
跟着JQuery API学Jquery 之二 属性
Apr 09 #Javascript
JSON 教程 json入门学习笔记
Sep 22 #Javascript
jquery.AutoComplete.js中文修正版(支持firefox)
Apr 09 #Javascript
javaScript call 函数的用法说明
Apr 09 #Javascript
javascript 自动填写表单的实现方法
Apr 09 #Javascript
Extjs入门之动态加载树代码
Apr 09 #Javascript
You might like
PHP递归返回值时出现的问题解决办法
2013/02/19 PHP
php 过滤英文标点符号及过滤中文标点符号代码
2014/06/12 PHP
PHP 与 UTF-8 的最佳实践详细介绍
2017/01/04 PHP
jQuery DOM操作小结与实例
2010/01/07 Javascript
javascript下判断一个元素是否存在的代码
2010/03/05 Javascript
深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!
2012/01/15 Javascript
javascript中判断一个值是否在数组中并没有直接使用
2012/12/17 Javascript
jquery easyui 结合jsp简单展现table数据示例
2014/04/18 Javascript
轻松创建nodejs服务器(7):阻塞操作的实现
2014/12/18 NodeJs
jQuery对象的selector属性用法实例
2014/12/27 Javascript
JS烟花背景效果实现方法
2015/03/03 Javascript
jQuery选择器源码解读(八):addCombinator函数
2015/03/31 Javascript
基于JS实现简单的样式切换效果代码
2015/09/04 Javascript
关于JS中match() 和 exec() 返回值和属性的测试
2016/03/21 Javascript
JavaScript数据类型学习笔记分享
2016/09/01 Javascript
基于HTML5+JS实现本地图片裁剪并上传功能
2017/03/24 Javascript
Bootstrap实现的标签页内容切换显示效果示例
2017/05/25 Javascript
利用Jasmine对Angular进行单元测试的方法详解
2017/06/12 Javascript
如何实现一个webpack模块解析器
2018/10/24 Javascript
vue-cli单页面预渲染seo-prerender-spa-plugin操作
2020/08/10 Javascript
Vue实现boradcast和dispatch的示例
2020/11/13 Javascript
[01:02:32]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第二场 2月26日
2021/03/11 DOTA
Python访问MySQL封装的常用类实例
2014/11/11 Python
Python中利用函数装饰器实现备忘功能
2015/03/30 Python
bpython 功能强大的Python shell
2016/02/16 Python
关于Python正则表达式 findall函数问题详解
2018/03/22 Python
对pandas的行列名更改与数据选择详解
2018/11/12 Python
DBA数据库管理员JAVA程序员架构师必看
2016/02/07 面试题
土木工程专业个人求职信
2013/12/05 职场文书
烹调加工管理制度
2014/02/04 职场文书
大学生党员自我批评
2014/02/14 职场文书
小学评语大全
2014/04/22 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL
redis限流的实际应用
2021/04/24 Redis
Python Django ORM连表正反操作技巧
2021/06/13 Python
python 判断文件或文件夹是否存在
2022/03/18 Python