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的获取mouse坐标插件的实现代码
Apr 01 Javascript
js href的用法
May 13 Javascript
js限制textarea每行输入字符串长度的代码
Oct 31 Javascript
给超链接添加特效鼠标移动展示提示信息且随鼠标移动
Oct 17 Javascript
jquery广告无缝轮播实例
Jan 05 Javascript
RequireJs的使用详解
Feb 19 Javascript
Angular如何引入第三方库的方法详解
Jul 13 Javascript
原生js封装添加class,删除class的实例
Nov 06 Javascript
使用ECharts实现状态区间图
Oct 25 Javascript
详解keep-alive + vuex 让缓存的页面灵活起来
Apr 19 Javascript
Layui 带多选框表格监听事件以及按钮自动点击写法实例
Sep 02 Javascript
面试中canvas绘制图片模糊图片问题处理
Mar 13 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页码形式分页函数支持静态化地址及ajax分页
2014/03/28 PHP
thinkPHP简单遍历数组方法分析
2016/05/16 PHP
php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法
2016/07/12 PHP
PHP查看SSL证书信息的方法
2016/09/22 PHP
php 查找数组元素提高效率的方法详解
2017/05/05 PHP
jquery 经典动画菜单效果代码
2010/01/26 Javascript
浅析LigerUi开发中谨慎载入common.css文件
2013/07/09 Javascript
js函数模拟显示桌面.scf程序示例
2014/04/20 Javascript
通过JS动态创建一个html DOM元素并显示
2014/10/15 Javascript
javascript相关事件的几个概念
2015/05/21 Javascript
js 中获取制定的cook信息实现方法
2016/11/19 Javascript
Vue-cli proxyTable 解决开发环境的跨域问题详解
2017/05/18 Javascript
vue resource post请求时遇到的坑
2017/10/19 Javascript
vue2.0 常用的 UI 库实例讲解
2017/12/12 Javascript
浅谈Vue2.0父子组件间事件派发机制
2018/01/08 Javascript
[02:46]2014DOTA2国际邀请赛 选手为你解读比赛MVP充满梦想
2014/07/09 DOTA
Python编写的com组件发生R6034错误的原因与解决办法
2013/04/01 Python
python实现支持目录FTP上传下载文件的方法
2015/06/03 Python
Scrapy框架CrawlSpiders的介绍以及使用详解
2017/11/29 Python
python中的迭代和可迭代对象代码示例
2017/12/27 Python
Python机器学习算法之k均值聚类(k-means)
2018/02/23 Python
VSCode中自动为Python文件添加头部注释
2019/11/14 Python
使用python去除图片白色像素的实例
2019/12/12 Python
python3中关于excel追加写入格式被覆盖问题(实例代码)
2020/01/10 Python
结合CSS3的布局新特征谈谈常见布局方法
2016/01/22 HTML / CSS
HTML5 使用 sessionStorage 进行页面传值的方法
2018/07/02 HTML / CSS
德国机车企业:FC-Moto
2017/10/27 全球购物
英国豪华文具和皮具配件经典老品牌:Smythson(斯迈森)
2018/04/19 全球购物
意大利珠宝店:Luxury Zone
2019/01/05 全球购物
新西兰最大的天然保健及护肤品网站:HealthPost(直邮中国)
2021/02/13 全球购物
Linux Interview Questions For software testers
2012/06/02 面试题
大型晚会策划方案
2014/02/06 职场文书
2015商场元旦促销活动策划方案
2014/12/09 职场文书
倡议书作文
2015/01/19 职场文书
毕业论文致谢范文
2015/05/14 职场文书
Win7/8.1用户可以免费升级到Windows 11系统吗?
2021/11/21 数码科技