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的AJAX用法
May 10 Javascript
jqgrid 简单学习笔记
May 03 Javascript
jquery写个checkbox——类似邮箱全选功能
Mar 19 Javascript
jQuery+ajax实现鼠标单击修改内容的思路
Jun 29 Javascript
jQuery标签替换函数replaceWith()的使用例子
Aug 28 Javascript
javascript实现动态统计图开发实例
Nov 21 Javascript
AngularJS实现给动态生成的元素绑定事件的方法
Dec 14 Javascript
使用vue-router设置每个页面的title方法
Feb 11 Javascript
解决iview打包时UglifyJs报错的问题
Mar 07 Javascript
Webpack打包字体font-awesome的方法示例
Apr 26 Javascript
10行代码实现微信小程序滑动tab切换
Dec 28 Javascript
js实现指定时间倒计时效果
Aug 26 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中根据变量的类型 选择echo或dump
2012/07/05 PHP
PHP二分查找算法示例【递归与非递归方法】
2016/09/29 PHP
laravel框架如何设置公共头和公共尾
2019/10/22 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
prototype 1.5相关知识及他人笔记
2006/12/16 Javascript
学习ExtJS accordion布局
2009/10/08 Javascript
基于JavaScript 类的使用详解
2013/05/07 Javascript
Jquery对数组的操作技巧整理
2014/03/25 Javascript
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例
2015/03/04 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
2015/11/29 Javascript
jQuery插件EasyUI获取当前Tab中iframe窗体对象的方法
2016/08/05 Javascript
node.js中的事件处理机制详解
2016/11/26 Javascript
JavaScript利用闭包实现模块化
2017/01/13 Javascript
jQuery实现简易的输入框字数计数功能示例
2017/01/16 Javascript
学习React中ref的两个demo示例
2018/08/14 Javascript
vue-cli 使用axios的操作方法及整合axios的多种方法
2018/09/12 Javascript
一次Webpack配置文件的分离实战记录
2018/11/30 Javascript
详解vuejs2.0 select 动态绑定下拉框支持多选
2019/04/25 Javascript
[44:37]完美世界DOTA2联赛PWL S3 Forest vs access 第一场 12.11
2020/12/13 DOTA
用Django实现一个可运行的区块链应用
2018/03/08 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
2020/07/20 Python
Python实现爬虫从网络上下载文档的实例代码
2018/06/13 Python
python入门:这篇文章带你直接学会python
2018/09/14 Python
python如何删除文件中重复的字段
2019/07/16 Python
Windows 平台做 Python 开发的最佳组合(推荐)
2020/07/27 Python
对CSS3选择器的研究(详解)
2016/09/16 HTML / CSS
铭万公司.net面试题笔试题
2014/07/20 面试题
一套Delphi的笔试题一
2016/02/14 面试题
学习十八届三中全会精神实施方案
2014/02/17 职场文书
社区交通安全实施方案
2014/03/22 职场文书
公司周年庆典策划方案
2014/05/17 职场文书
励志演讲稿200字
2014/08/21 职场文书
2015年植树节活动总结
2015/02/06 职场文书
2015年新农合工作总结
2015/03/30 职场文书
golang 实现时间戳和时间的转化
2021/05/07 Golang