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 点击按钮显示和隐藏层的代码
Jul 25 Javascript
JS去除数组重复值的五种不同方法
Sep 06 Javascript
js实现连个数字相加而不是拼接的方法
Feb 23 Javascript
JS中递归函数
Jun 17 Javascript
Javascript 实现放大镜效果实例详解
Dec 03 Javascript
Bootstrap BootstrapDialog使用详解
Feb 17 Javascript
jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】
Mar 21 jQuery
Vue Ajax跨域请求实例详解
Jun 20 Javascript
微信小程序图片轮播组件gallery slider使用方法详解
Jan 31 Javascript
在Vue项目中引入腾讯验证码服务的教程
Apr 03 Javascript
vue之将echart封装为组件
Jun 02 Javascript
Angular4.x Event (DOM事件和自定义事件详解)
Oct 09 Javascript
跟着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/06/10 PHP
PHP常用编译参数中文说明
2014/09/27 PHP
PHP输出九九乘法表代码实例
2015/03/27 PHP
PHP+ajax分页实例简析
2015/12/07 PHP
微信随机生成红包金额算法php版
2016/07/21 PHP
PHP微商城开源代码实例
2019/03/27 PHP
php装饰者模式简单应用案例分析
2019/10/23 PHP
yepnope.js 异步加载资源文件
2011/09/08 Javascript
五段实用的js高级技巧
2011/12/20 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
ES6新特性之模块Module用法详解
2017/04/01 Javascript
详解如何让Express支持async/await
2017/10/09 Javascript
解决Layui数据表格中checkbox位置不居中的方法
2018/08/15 Javascript
vue+axios+promise实际开发用法详解
2018/10/15 Javascript
微信小程序实现登录注册tab切换效果
2020/12/29 Javascript
Element Collapse 折叠面板的使用方法
2020/07/26 Javascript
[00:57]英雄,你的补给到了!
2020/11/13 DOTA
python fabric实现远程部署
2017/01/05 Python
Python利用multiprocessing实现最简单的分布式作业调度系统实例
2017/11/14 Python
Python获取指定文件夹下的文件名的方法
2018/02/06 Python
Python中正反斜杠(‘/’和‘\’)的意义与用法
2019/08/12 Python
通过python连接Linux命令行代码实例
2020/02/18 Python
使用jTopo给Html5 Canva中绘制的元素添加鼠标事件
2014/05/15 HTML / CSS
详解HTML5将footer置于页面最底部的方法(CSS+JS)
2018/10/11 HTML / CSS
AmazeUI 评论列表的实现示例
2020/08/13 HTML / CSS
C++是不是类型安全的
2014/02/18 面试题
专科应届生求职信
2013/11/24 职场文书
应届毕业生应聘自荐信
2013/12/07 职场文书
简短大学毕业感言
2014/01/18 职场文书
检察机关个人对照检查材料
2014/09/15 职场文书
机关干部个人对照检查材料思想汇报
2014/09/28 职场文书
销售经理工作检讨书
2015/02/19 职场文书
行政司机岗位职责
2015/04/10 职场文书
解析Java中的static关键字
2021/06/14 Java/Android
Windows Server 2012 R2 磁盘分区教程
2022/04/29 Servers
Nginx如何配置根据路径转发详解
2022/07/23 Servers