也说 Jquery+ASP.NET 实现开心网上传头像剪裁功能
前几天博客园cnblogs里有个朋友发了一个类似的帖子(你可以点这里查看),刚刚也要做这个功能,但是原来程序稍微有点问题,特别在前台上有几处不合理的地方,所以就着开心网的代码重写一下,效果如下
Step 1 选择上传照片
Step2 ,点击上传一张图片,默认缩放到刚好填充画布,如果图片小于画布就不缩放了,并且将图片集中
缩放图片是,以画布中的选取框为中,向四周扩散,缩小
点击保存按钮 保存截取后的图片
来看下代码吧
前台:需要引用Jquery的类库和两个Ui的Js
<script type="text/javascript" src="js/jquery1.2.6.pack.js"></script>
<script type="text/javascript" src="js/ui.core.packed.js" ></script>
<script type="text/javascript" src="js/ui.draggable.packed.js" ></script>
html太长就不全贴出来了,挑几个重点来说把:
1:这个我们的html片段
2:这个是开心网中的html片段
开心网中用一个table作为画布的架子,中间的一个td设置样式为选取框,把img移到table下面,就可以看到上图的效果了,但是在设置drap的时候handler设置为table(id=crop),来看下下面开心网的代码就知道了。
因为我们点击的时候,因为table在img之上,所以点击只能点到table。但是Jquery的drap handle不能设置源以外的元素,所以上面的方法就行不通了,参考了原文中的做法,用两个图片代替,一个做成蒙层的效果(ImageDragContainer),一个缩小放到中间的位置,变成剪切窗口(IconContainer),只要控制好两个图片的left,top,width,height,那么可以做到看上去像一个图片那样。如前面的效果所示。
其他html就是一些布局,上传控件和几个用于存放值的textbox了,就不介绍了,来看下js把,关键的,都加上注释了。有问题可以留言交流
//全局变量定义
var CANVAS_WIDTH = 284; //画布的宽
var CANVAS_HEIGHT = 266; //画布的高
var ICON_SIZE = 120; //截取框的大小,正方形
var LEFT_EDGE = (CANVAS_WIDTH - ICON_SIZE) / 2; //82
var TOP_EDGE = (CANVAS_HEIGHT - ICON_SIZE) / 2; //73
var CANVAS_LEFT_MARGIN = 4;
//用document. ready事件中在上传后第一次转向时无法获取到图片的实际宽度和高度,应该是没有被下载来的缘故
$(window).load(function() {
var $iconElement = $("#ImageIcon");
var $imagedrag = $("#ImageDrag");
//获取上传图片的实际高度,宽度
var image = new Image();
image.src = $iconElement.attr("src");
var realWidth = image.width;
var realHeight = image.height;
image = null;
//计算缩放比例开始
var minFactor = ICON_SIZE / Math.max(realWidth, realHeight);
if (ICON_SIZE > realWidth && ICON_SIZE > realHeight) {
minFactor = 1;
}
var factor = minFactor > 0.25 ? 8.0 : 4.0 / Math.sqrt(minFactor);
//图片缩放比例
var scaleFactor = 1;
if (realWidth > CANVAS_WIDTH && realHeight > CANVAS_HEIGHT) {
if (realWidth / CANVAS_WIDTH > realHeight / CANVAS_HEIGHT) {
scaleFactor = CANVAS_HEIGHT / realHeight;
}
else {
scaleFactor = CANVAS_WIDTH / realWidth;
}
}
//计算缩放比例结束
//设置滑动条的位置,设置滑动条的值的变化来改变缩放率是一个非线性的变化,而是幂函数类型 即类似y=factor(X)--此处x为幂指数
//此处100 * (Math.log(scaleFactor * factor) / Math.log(factor)) 为知道y 求解x,scaleFactor 即为y 此处的100为 中间值,滑动条长度为200
$(".child").css("left", 100 * (Math.log(scaleFactor * factor) / Math.log(factor)) + "px");
//图片实际尺寸,并近似到整数
var currentWidth = Math.round(scaleFactor * realWidth);
var currentHeight = Math.round(scaleFactor * realHeight);
//图片相对CANVAS的初始位置,图片相对画布居中
var originLeft = Math.round((CANVAS_WIDTH - currentWidth) / 2) ;
var originTop = Math.round((CANVAS_HEIGHT - currentHeight) / 2);
//计算截取框中的图片的位置
var dragleft = originLeft - LEFT_EDGE;
var dragtop = originTop - TOP_EDGE;
//设置图片当前尺寸和位置
$iconElement.css({ width: currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
$imagedrag.css({ width: currentWidth + "px", height: currentHeight + "px", left: dragleft + "px", top: dragtop + "px" });
//初始化默认值
$("#txt_width").val(currentWidth);
$("#txt_height").val(currentHeight);
$("#txt_top").val(0-dragtop);
$("#txt_left").val(0-dragleft);
$("#txt_Zoom").val(scaleFactor);
var oldWidth = currentWidth;
var oldHeight = currentHeight;
//设置图片可拖拽,并且拖拽一张图片时,同时移动另外一张图片
$imagedrag.draggable(
{
cursor: 'move',
drag: function(e, ui) {
var self = $(this).data("draggable");
var drop_img = $("#ImageIcon");
var top = drop_img.css("top").replace(/px/, ""); //取出截取框到顶部的距离
var left = drop_img.css("left").replace(/px/, ""); //取出截取框到左边的距离
drop_img.css({ left: (parseInt(self.position.left) + LEFT_EDGE) + "px", top: (parseInt(self.position.top) + TOP_EDGE) + "px" }); //同时移动内部的图片
$("#txt_left").val(0 - parseInt(self.position.left));
$("#txt_top").val(0 - parseInt(self.position.top));
}
}
);
//设置图片可拖拽,并且拖拽一张图片时,同时移动另外一张图片
$iconElement.draggable(
{
cursor: 'move',
drag: function(e, ui) {
var self = $(this).data("draggable");
var drop_img = $("#ImageDrag");
var top = drop_img.css("top").replace(/px/, ""); //取出截取框到顶部的距离
var left = drop_img.css("left").replace(/px/, ""); //取出截取框到左边的距离
drop_img.css({ left: (parseInt(self.position.left) - LEFT_EDGE) + "px", top: (parseInt(self.position.top) - TOP_EDGE) + "px" }); //同时移动内部的图片
$("#txt_left").val(0 - (parseInt(self.position.left) - LEFT_EDGE));
$("#txt_top").val(0 - (parseInt(self.position.top) - TOP_EDGE));
}
}
);
//缩放的代码,要缩放以截取框为中心,所以要重新计算图片的left和top
$(".child").draggable(
{
cursor: "move", containment: $("#bar"),
drag: function(e, ui) {
var left = parseInt($(this).css("left"));
//前面讲过了y=factor(x),此处是知道x求y的值,即知道滑动条的位置,获取缩放率
scaleFactor = Math.pow(factor, (left / 100 - 1));
if (scaleFactor < minFactor) {
scaleFactor = minFactor;
}
if (scaleFactor > factor) {
scaleFactor = factor;
}
//以下代码同初始化过程,因为用到局部变量所以没有
var iconElement = $("#ImageIcon");
var imagedrag = $("#ImageDrag");
var image = new Image();
image.src = iconElement.attr("src");
var realWidth = image.width;
var realHeight = image.height;
image = null;
//图片实际尺寸
var currentWidth = Math.round(scaleFactor * realWidth);
var currentHeight = Math.round(scaleFactor * realHeight);
//图片相对CANVAS的初始位置
var originLeft = parseInt(iconElement.css("left"));
var originTop = parseInt(iconElement.css("top"));
originLeft -= Math.round((currentWidth - oldWidth) / 2);
originTop -= Math.round((currentHeight - oldHeight) / 2);
dragleft = originLeft - LEFT_EDGE;
dragtop = originTop - TOP_EDGE;
//图片当前尺寸和位置
iconElement.css({ width: currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
imagedrag.css({ width: currentWidth + "px", height: currentHeight + "px", left: dragleft + "px", top: dragtop + "px" });
$("#txt_Zoom").val(scaleFactor);
$("#txt_left").val(0 - dragleft);
$("#txt_top").val(0 - dragtop);
$("#txt_width").val(currentWidth);
$("#txt_height").val(currentHeight);
oldWidth = currentWidth;
oldHeight = currentHeight;
}
});
var SilderSetValue = function(i) {
var left = parseInt($(".child").css("left"));
left += i;
if (left < 0) {
left = 0;
}
if (left > 200) {
left = 200;
}
scaleFactor = Math.pow(factor, (left / 100 - 1));
if (scaleFactor < minFactor) {
scaleFactor = minFactor;
}
if (scaleFactor > factor) {
scaleFactor = factor;
}
var iconElement = $("#ImageIcon");
var imagedrag = $("#ImageDrag");
var image = new Image();
image.src = iconElement.attr("src");
var realWidth = image.width;
var realHeight = image.height;
image = null;
//图片实际尺寸
var currentWidth = Math.round(scaleFactor * realWidth);
var currentHeight = Math.round(scaleFactor * realHeight);
//图片相对CANVAS的初始位置
var originLeft = parseInt(iconElement.css("left"));
var originTop = parseInt(iconElement.css("top"));
originLeft -= Math.round((currentWidth - oldWidth) / 2);
originTop -= Math.round((currentHeight - oldHeight) / 2);
dragleft = originLeft - LEFT_EDGE;
dragtop = originTop - TOP_EDGE;
//图片当前尺寸和位置
$(".child").css("left", left + "px");
iconElement.css({ width: currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
imagedrag.css({ width: currentWidth + "px", height: currentHeight + "px", left: dragleft + "px", top: dragtop + "px" });
$("#txt_Zoom").val(scaleFactor);
$("#txt_left").val(0 - dragleft);
$("#txt_top").val(0 - dragtop);
$("#txt_width").val(currentWidth);
$("#txt_height").val(currentHeight);
oldWidth = currentWidth;
oldHeight = currentHeight;
}
//点击加减号的事件 ,滑动条一共200px,点击一下+-20px
$("#moresmall").click(function() {
SilderSetValue(-20);
});
$("#morebig").click(function() {
SilderSetValue(20);
});
});
后台的代码相对简单,上传保存,通过textbox中的参数进行图片切割,也比较简单,来看下分为两个,一个是缩放裁剪,一个原图裁剪,代码参考原文。
{
using (Image originalImg = Image.FromFile(pPath))
{
if (originalImg.Width == imageWidth && originalImg.Height == imageHeight)
{
return SaveCutPic(pPath, pSavedPath, pPartStartPointX, pPartStartPointY, pPartWidth, pPartHeight,
pOrigStartPointX, pOrigStartPointY);
}
string filename = DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";
string filePath = pSavedPath + "\\" + filename;
Bitmap thumimg =MakeThumbnail(originalImg, imageWidth, imageHeight);
Bitmap partImg = new Bitmap(pPartWidth, pPartHeight);
Graphics graphics = Graphics.FromImage(partImg);
Rectangle destRect = new Rectangle(new Point(pPartStartPointX, pPartStartPointY), new Size(pPartWidth, pPartHeight));//目标位置
Rectangle origRect = new Rectangle(new Point(pOrigStartPointX, pOrigStartPointY), new Size(pPartWidth, pPartHeight));//原图位置(默认从原图中截取的图片大小等于目标图片的大小)
///文字水印
Graphics G = Graphics.FromImage(partImg);
//Font f = new Font("Lucida Grande", 6);
//Brush b = new SolidBrush(Color.Gray);
G.Clear(Color.White);
// 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。
G.InterpolationMode = InterpolationMode.HighQualityBicubic;
// 指定高质量、低速度呈现。
G.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawImage(thumimg, destRect, origRect, GraphicsUnit.Pixel);
//G.DrawString("Xuanye", f, b, 0, 0);
G.Dispose();
originalImg.Dispose();
if (File.Exists(filePath))
{
File.SetAttributes(filePath, FileAttributes.Normal);
File.Delete(filePath);
}
partImg.Save(filePath, ImageFormat.Jpeg);
partImg.Dispose();
thumimg.Dispose();
return filename;
}
}
public static Bitmap MakeThumbnail(Image fromImg, int width, int height)
{
Bitmap bmp = new Bitmap(width, height);
int ow = fromImg.Width;
int oh = fromImg.Height;
//新建一个画板
Graphics g = Graphics.FromImage(bmp);
//设置高质量插值法
g.InterpolationMode = InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode =SmoothingMode.HighQuality;
//清空画布并以透明背景色填充
g.Clear(Color.Transparent);
g.DrawImage(fromImg, new Rectangle(0, 0, width, height),
new Rectangle(0, 0, ow, oh),
GraphicsUnit.Pixel);
return bmp;
}
public static string SaveCutPic(string pPath, string pSavedPath, int pPartStartPointX, int pPartStartPointY, int pPartWidth, int pPartHeight, int pOrigStartPointX, int pOrigStartPointY)
{
string filename = DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";
string filePath = pSavedPath + "\\" + filename;
using (Image originalImg = Image.FromFile(pPath))
{
Bitmap partImg = new Bitmap(pPartWidth, pPartHeight);
Graphics graphics = Graphics.FromImage(partImg);
Rectangle destRect = new Rectangle(new Point(pPartStartPointX, pPartStartPointY), new Size(pPartWidth, pPartHeight));//目标位置
Rectangle origRect = new Rectangle(new Point(pOrigStartPointX, pOrigStartPointY), new Size(pPartWidth, pPartHeight));//原图位置(默认从原图中截取的图片大小等于目标图片的大小)
///注释 文字水印
Graphics G = Graphics.FromImage(partImg);
//Font f = new Font("Lucida Grande", 6);
//Brush b = new SolidBrush(Color.Gray);
G.Clear(Color.White);
// 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。
G.InterpolationMode = InterpolationMode.HighQualityBicubic;
// 指定高质量、低速度呈现。
G.SmoothingMode = SmoothingMode.HighQuality;
graphics.DrawImage(originalImg, destRect, origRect, GraphicsUnit.Pixel);
//G.DrawString("Xuanye", f, b, 0, 0);
G.Dispose();
originalImg.Dispose();
if (File.Exists(filePath))
{
File.SetAttributes(filePath, FileAttributes.Normal);
File.Delete(filePath);
}
partImg.Save(filePath, ImageFormat.Jpeg);
partImg.Dispose();
}
return filename;
}
}
转载请说明出处
完整代码下载
转载于:https://www.cnblogs.com/xuanye/archive/2008/09/25/1299091.html
也说 Jquery+ASP.NET 实现开心网上传头像剪裁功能相关推荐
- Jquery+ASP.NET 实现开心网上传头像剪裁功能[转]
from:http://www.cnblogs.com/xuanye/archive/2008/09/25/1299091.html 前几天博客园cnblogs里有个朋友发了一个类似的帖子(你可以点这 ...
- jQuery 自制上传头像插件-附带Demo实例(ajaxfileupload.js第三弹)
这篇文章主要是对前两篇关于ajaxfileupload.js插件的文章 <ASP.NET 使用ajaxfileupload.js插件出现上传较大文件失败的解决方法(ajaxfileupload. ...
- ajax图片上传插件demo,jQuery 自制上传头像插件-附带Demo实例(ajaxfileupload.js第三弹)...
这篇文章主要是对前两篇关于ajaxfileupload.js插件的文章 的一个收关.但是最初也是因为想做这么一个功能,一点一点的引发出了好多问题,不断去学习,研究,才写了这三篇. 早些时候已经实现了上 ...
- asp毕业设计——基于asp+access的校园网上购物平台设计与实现(毕业论文+程序源码)——网上购物平台
基于asp+access的校园网上购物平台设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于asp+access的校园网上购物平台设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦. ...
- C#毕业设计——基于C#+asp.net+sqlserver的网上鲜花销售系统设计与实现(毕业论文+程序源码)——鲜花销售系统
基于C#+asp.net+sqlserver的网上鲜花销售系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+sqlserver的网上鲜花销售系统设计与实现,文章末尾 ...
- C#毕业设计——基于C#+asp.net+Access的网上同学录系统设计与实现(毕业论文+程序源码)——网上同学录系统
基于C#+asp.net+Access的网上同学录系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+Access的网上同学录系统设计与实现,文章末尾附有本毕业设计的 ...
- C#毕业设计——基于C#+asp.net+sqlserver的网上人才招聘系统设计与实现(毕业论文+程序源码)——人才招聘系统
基于C#+asp.net+sqlserver的网上人才招聘系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+sqlserver的网上人才招聘系统设计与实现,文章末尾 ...
- C#毕业设计——基于C#+asp.net+sqlserver的网上教材管理系统设计与实现(毕业论文+程序源码)——教材管理系统
基于C#+asp.net+sqlserver的网上教材管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+sqlserver的网上教材管理系统设计与实现,文章末尾 ...
- ASP.NET MVC3 上传头像图片并截图
关于上传头像并且截图网上应该有很多资料,大多都是JQuery插件,用起来不是很方便 本文所介绍的方法将快速完成一个"上传头像图片并截图",只需要修改少量的代码 我们先来看看完成后的 ...
最新文章
- Codeforces 1326F Wise Men (容斥原理、状压 DP、划分数)
- 思科设备路由器间IPsec ×××实现私网之间通信实战
- 8.var目录下的文件和目录详解
- php真随机数,php 的伪随机数与真随机数实例详解
- [精华] VI高级命令集锦
- 学习ecshop 教程网址
- 面向对象 “上”
- 易筋SpringBoot 2.1 | 第廿四篇:SpringBoot访问Docker中的MongoDB
- Linux消息队列的设置及查看
- 学机器学习怎么可以不知道最小二乘法
- windows环境下搭建ftp服务和web服务,实现图片服务器功能
- 解决Mscomctl.ocx丢失的问题
- 玩转Python量化金融工具之NumPy
- 软件测试报告【样本】
- 哈工大硕士生实现 11 种数据降维算法,代码已开源!
- WinInet + MFC 写vc驿站助手
- nodej.s 搭建一个socket服务(原生和sockjs)
- 关于目标跟踪SiamMask的Youtube-VOS 数据库下载
- 学生免费申请idea时收不到确认邮件已解决
- PMP新考纲 敏捷题目 (三)
热门文章
- linux用户空间内存分布,了解linux 64位地址空间内存布局
- 配置豪华的 Windows 开发环境
- 分享一款好看的城市选择器
- 未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryService...匹配的导出...
- .NET导入导出Excel
- FreeBSD 恢复root密码-FreeBSD 5 或都之后版本.
- 面试题51. 数组中的逆序对
- python怎么设置画布颜色_如何在kivy python中动态更改画布颜色?
- 必须用Python给程序员不懂浪漫平反一波....不管班花还是校花全都跑不掉~
- oracle 监听报错,解决Oracle监听服务报错