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 相关文章推荐
lib.utf.js
Aug 21 Javascript
找到了一篇jQuery与Prototype并存的冲突的解决方法
Aug 29 Javascript
jquery遍历checkbox介绍
Feb 21 Javascript
jquery控制select的text/value值为选中状态
Jun 03 Javascript
javascript滚轮控制模拟滚动条
Oct 19 Javascript
bootstrap fileinput组件整合Springmvc上传图片到本地磁盘
May 11 Javascript
使用vue如何构建一个自动建站项目
Feb 05 Javascript
vue组件中的数据传递方法
May 14 Javascript
微信小程序云开发之使用云存储
May 17 Javascript
react PropTypes校验传递的值操作示例
Apr 28 Javascript
解决vue cli4升级sass-loader(v8)后报错问题
Jul 30 Javascript
uniapp微信小程序实现一个页面多个倒计时
Nov 01 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
一个好用的分页函数
2006/11/16 PHP
php中用数组的方法设置cookies
2011/04/21 PHP
PHP的MVC模式实现原理分析(一相简单的MVC框架范例)
2014/04/29 PHP
使一个函数作为另外一个函数的参数来运行的javascript代码
2007/08/13 Javascript
JS类定义原型方法的两种实现的区别评论很多
2007/09/12 Javascript
jQuery对象[0]是什么含义?
2010/07/31 Javascript
javascript打印输出json实例
2013/11/11 Javascript
Jquery 切换不同图片示例代码
2013/12/05 Javascript
node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用
2014/11/04 Javascript
HTML,CSS,JavaScript速查表推荐
2014/12/02 Javascript
所见即所得的富文本编辑器bootstrap-wysiwyg使用方法详解
2016/05/27 Javascript
jQuery自定义数值抽奖活动代码
2016/06/11 Javascript
jQuery基本选择器之标签名选择器
2016/09/03 Javascript
基于vue.js实现图片轮播效果
2016/12/01 Javascript
利用Bootstrap实现表格复选框checkbox全选
2016/12/21 Javascript
js图片延迟加载(Lazyload)三种实现方式
2017/03/01 Javascript
Vue 仿QQ左滑删除组件功能
2018/03/12 Javascript
微信小程序自定义底部导航带跳转功能
2018/11/27 Javascript
JavaScript实现简单贪吃蛇效果
2020/03/09 Javascript
vue实现广告栏上下滚动效果
2020/11/26 Vue.js
用Python计算三角函数之atan()方法的使用
2015/05/15 Python
CentOS下使用yum安装python-pip失败的完美解决方法
2017/08/16 Python
Python WXPY实现微信监控报警功能的代码
2017/10/20 Python
python 从csv读数据到mysql的实例
2018/06/21 Python
pandas中遍历dataframe的每一个元素的实现
2019/10/23 Python
Flask框架 CSRF 保护实现方法详解
2019/10/30 Python
Python使用Turtle库绘制一棵西兰花
2019/11/23 Python
python实现图片转换成素描和漫画格式
2020/08/19 Python
戴尔马来西亚官网:Dell Malaysia
2020/05/02 全球购物
普天C++笔试题
2016/03/20 面试题
大学同学十年聚会感言
2014/02/21 职场文书
建材投资建议书
2014/05/16 职场文书
财务整改报告范文
2014/11/05 职场文书
公司人事任命通知
2015/04/20 职场文书
基于Redis6.2.6版本部署Redis Cluster集群的问题
2022/04/01 Redis
Spring中bean集合注入的方法详解
2022/07/07 Java/Android