头像裁剪是一个经常用到的功能,实现原理也较为简单,就是在本地选择好所需裁剪图片的坐标,将坐标发送到服务器,由服务器执行图片裁剪操作。

jQuery插件Jcrop提供了强大的图片裁剪坐标选择插件。一下来介绍它的用法。本处采用了AJAX本地上传一张图片的方法让用户裁剪。很多验证没有做,因为作为一个关于Jcrop的例子,很多验证不如与本文研究的范畴。服务器端采用MVC3实现。

直接贴代码,详解注释里面有了。

一、前台页面代码。

<link href="http://www.cnblogs.com/Content/jquery.Jcrop.css" rel="stylesheet" type="text/css" />
<script src="http://www.cnblogs.com/Content/jquery-1.7.1.js" type="text/javascript"></script>
<script src="http://www.cnblogs.com/Content/ajaxfileupload.js" type="text/javascript"></script>
<script src="http://www.cnblogs.com/Content/jquery.Jcrop.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$(":button").click(function () {
//当点击上传按钮时,AJAX上传图片到服务器
ajaxFileUpload();
})
}) //当裁剪框变动时,将左上角相对图片的X坐标与Y坐标,宽度以及高度放到<input type="hidden">中(上传到服务器上裁剪会用到)
function showCoords(c) {
$("#p1").text(c.x + " " + c.y + " " + c.w + " " + c.h );
$("#x1").val(c.x);
$("#y1").val(c.y);
$("#cw").val(c.w);
$("#ch").val(c.h); } //当AJAX上传图片操作
function ajaxFileUpload() {
$.ajaxFileUpload
(
{
url: '/uploadandcut/upload?action=up', //用于文件上传的服务器端请求地址up参数标记此次是上传操作还是裁剪操作
secureuri: false, //一般设置为false,是否安全上传
fileElementId: 'file1', //文件上传控件的id属性 <input type="file" id="file" name="file" />
dataType: 'json', //返回值类型 一般设置为json 期望服务器传回的数据类型
success: function (data, status) //服务器成功响应处理函数
{
//上传成功后在将服务器上刚刚上传的图片显示在img1上
$("#img1").attr("src", data.imgurl);
if (typeof (data.error) != 'undefined') {
if (data.error != '') {
alert(data.error);
} else {
alert(data.msg);
}
} //同时启动裁剪操作,触发裁剪框显示,让用户选择图片区域
$("#img1").Jcrop({
bgColor: 'black',
bgOpacity: .4,
setSelect: [100, 100, 150,150], //设定4个角的初始位置
aspectRatio: 1 / 1,
onChange: showCoords, //当裁剪框变动时执行的函数
onSelect: showCoords, //当选择完成时执行的函数
}); },
error: function (data, status, e)//服务器响应失败处理函数
{
alert(e);
}
}
)
return false;
}
</script> <div>
<p><input type="file" id="file1" name="file" /></p>
<input type="button" value="上传" />
<p><img id="img1" alt="上传成功啦!" src="" /></p>
<p id="p1"></p> <form id="FaceUpload" name="FaceUpload" method="post" enctype="multipart/form-data" action="/uploadandcut/Upload?action=cut">
<input type="hidden" id="x1" name="x1" value="0" />
<input type="hidden" id="y1" name="y1" value="0" />
<input type="hidden" id="cw" name="cw" value="0" />
<input type="hidden" id="ch" name="ch" value="0" />
<input type="submit" value="裁剪上传" />
</form> </div>

二、后台代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Drawing; namespace UploadAndCut.Controllers
{
public class UploadAndCutController : Controller
{
/// <summary>
/// 打开页面
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
return View();
} /// <summary>
/// 上传操作,包括提交表单与AJAX上传图片
/// </summary>
/// <returns></returns>
public ActionResult Upload()
{
string action = HttpContext.Request.QueryString["action"];
//判断用户的操作类型
switch (action.ToLower())
{
#region 当为上传图片操作时
case "up":
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile())
{
continue;
}
string ExtensionName = Path.GetExtension(Request.Files[upload].FileName).ToLower();
if (ExtensionName != ".jpg" && ExtensionName != ".png" && ExtensionName != ".gif" && ExtensionName != ".bmp")
{
return Redirect("/Tips/tip?error=您上传的图片不符合格式!");
}
string ImgPath = Server.MapPath("/uploads/" + "img" + ExtensionName);
Request.Files[upload].SaveAs(ImgPath);
}
string error = "";
string msg = "上传成功";
string imgurl = "/uploads/img.jpg";
string res = "{ error:'" + error + "', msg:'" + msg + "',imgurl:'" + imgurl + "'}";
return Content(res);
break;
#endregion #region 当为裁剪图片操作时
case "cut":
string strx1 = HttpContext.Request.Form["x1"];
string stry1 = HttpContext.Request.Form["y1"];
string strcw = HttpContext.Request.Form["cw"];
string strch = HttpContext.Request.Form["ch"];
int intx1 = Convert.ToInt32(strx1);
int inty1 = Convert.ToInt32(stry1);
int intcw = Convert.ToInt32(strcw);
int intch = Convert.ToInt32(strch); Stream imgStream = GetLocalStream(Server.MapPath("/uploads/" + "img.jpg"));
//System.Drawing.Image initImage = System.Drawing.Image.FromStream(imgStream);
Cut(imgStream, Server.MapPath("/uploads/img.jpg"), intx1, inty1, intcw, intch, 100);
return Redirect("/uploadandcut/index");
break;
#endregion default:
return null;
break;
}
} /// <summary>
/// 将一个文件读成字符流
/// </summary>
/// <param name="InFilePath"></param>
/// <returns></returns>
public static Stream GetLocalStream(string InFilePath)
{
return new MemoryStream(ReadFileReturnBytes(InFilePath));
} /// <summary>从文件中读取二进制数据</summary>
/// <param name="filePath">文件路径</param>
/// <returns> byte[]二进制数据</returns>
public static byte[] ReadFileReturnBytes(string filePath)
{
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader br = new BinaryReader(fs);
byte[] buff = br.ReadBytes((int)fs.Length);
br.Close();
fs.Close();
return buff;
} #region 裁剪操作
public static void Cut(System.IO.Stream fromFile, string fileSaveUrl, int xPosition, int yPosition, int width, int height, int quality)
{
//创建目录
//原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)
System.Drawing.Image initImage = System.Drawing.Image.FromStream(fromFile, true);
//原始图片的宽、高
int initWidth = initImage.Width;
int initHeight = initImage.Height;
if (xPosition + width > initWidth)
width = initWidth - xPosition;
if (yPosition + height > initHeight)
height = initHeight - yPosition;
//与原图相等直接保存
if ((width >= initWidth && height >= initHeight) || (width < 1 && height < 1))
{
initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
}
else
{
System.Drawing.Image pickedImage = null;
System.Drawing.Graphics pickedG = null;
//对象实例化
pickedImage = new System.Drawing.Bitmap(width, height);
pickedG = System.Drawing.Graphics.FromImage(pickedImage);
//设置质量
pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//定位
System.Drawing.Rectangle fromR = new System.Drawing.Rectangle(xPosition, yPosition, width, height);
System.Drawing.Rectangle toR = new System.Drawing.Rectangle(0, 0, width, height);
//画图
pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
//关键质量控制
//获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
System.Drawing.Imaging.ImageCodecInfo[] icis = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.ImageCodecInfo ici = null;
foreach (System.Drawing.Imaging.ImageCodecInfo i in icis)
{
if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif")
{
ici = i;
}
}
System.Drawing.Imaging.EncoderParameters ep = new System.Drawing.Imaging.EncoderParameters(1);
ep.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);
//保存缩略图
pickedImage.Save(fileSaveUrl, ici, ep);
//释放关键质量控制所用资源
ep.Dispose();
//释放截图资源
pickedG.Dispose();
pickedImage.Dispose();
//释放原始图片资源
initImage.Dispose();
}
}
#endregion
}
}

还有一个扩展方法,在DEMO里面会有,不粘贴了。DEMO下载地址

jQuery之Jcrop的更多相关文章

  1. 使用JQuery插件Jcrop进行图片截取

    Jcrop插件本身并不含有图片截取功能,它仅仅是在前端层面构建一套截取动画效果并产生4个坐标点,插件使用者将这4个坐标点传回至服务器接口上进行截取操作.其优点是具有较高的通用性.浏览器兼容性(IE6+ ...

  2. 对jquery插件Jcrop开发一个裁剪组件

    Jcrop是一款优秀的裁剪工具,它不仅可以裁剪图像,还可以裁剪canvas及任何的div元素,具体可参考: http://code.ciaoca.com/jquery/jcrop/ 基于Jcrop,开 ...

  3. 实现图像剪裁 jquery.Jcrop

       配合 jquery.Jcrop 实现上传图片进行剪裁保存功能    <script src="js/jquery.min.js"></script> ...

  4. JCrop+GraphicsMagick+Im4Java 实现图像裁减

    Im4Java的安装文档见:http://blog.csdn.net/tangpengtao/article/details/9208047 JCrop的插件:jquery.Jcrop.js jQue ...

  5. .NET + Jcrop 实现在线裁图功能

    最近有这样一个需求,因为一个门户网站首页展示图片很长但很矮,自己截图怕有不到位,所以利用JQUERY 的 Jcrop组件做了一个在线裁图的功能. 初始化 $('#oldpicImg').Jcrop({ ...

  6. 前端:jQuery笔记

    前端:jQuery笔记 此系列文章乃是学习jQuery的学习笔记. Asp.net MVC Comet推送 摘要: 一.简介 在Asp.net MVC实现的Comet推送的原理很简单. 服务器端:接收 ...

  7. 在asp.net中使用jQuery实现类似QQ网站的图片切割效果

    今天要给大家介绍一个asp.net结合jQuery来切割图片的小程序,原理很简单,大致流程是: 加载原图 --> 用矩形框在原图上选取区域并将选取的顶点坐标和矩形尺寸发送至服务器 --> ...

  8. ASP.NET MVC4使用JCrop裁剪图片并上传

    需要用到的jquery插件Jcrop .Jquery.form 百度webuploader插件( http://fex.baidu.com/webuploader/ ) 引用下载好的css和js文件 ...

  9. Asp.net MVC 实现图片上传剪切

    使用技术:Asp.net MVC与jquery.uploadify,Jcrop 首先上页面 01 <strong><!DOCTYPE html> 02  <html> ...

随机推荐

  1. Qt编程之信号与槽-------unresolved external symbol "public: virtual struct QMetaObject const * __thiscall XX::metaObject(void)const

    原因是加入Q_OBJECT这个macro的类,被编译的时候就要用到moc这个命令,所以在VS2010中,没有加入此命令的应用,当然会出错了.所以解决办法是加,或者如果你不使用信号槽可以直接删除. 当要 ...

  2. 时间类处理<1>

    2016/05/31 14:47:21 [emerg] 14629#0: location "/nginx_status" is outside location "/p ...

  3. Android Studio 配置SVN实现代码管理

    Refference From:http://iaiai.iteye.com/blog/2267346 一.Android Studio配置SVN Android Studio关联配置SVN很简单,在 ...

  4. ps&&/proc/pid/xxx

    ps 如果想看一个进程的启动时间,可以用lstart来看 [root@jiangyi02.sqa.zmf /home/ahao.mah] #ps -eo pid,lstart,etime,cmd |g ...

  5. UGUI 帧动画插件

    最近在开发一款功夫猫游戏,本来使用Unity Sprite制作,但是发现Sprite对各种分辨率不支持. 看着游戏很简单就使用UGUI制作,在中途发现有很多帧动画播放,使用了Animation调整使用 ...

  6. qt反走样(简选)

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #qt反走样(简选) #概念 """ ...

  7. Android窗口管理服务WindowManagerService显示Activity组件的启动窗口(Starting Window)的过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8577789 在Android系统中,Activ ...

  8. 设计一个算法,求非空二叉树中指定的第k层(k&gt;1)的叶子节点的个数

    思想:採用基于层序遍历的方法. 用level扫描各层节点,若某一层的节点出队后.rear指向该层中最右节点.则将rear赋值给last(对于第一层.last=1).在出队时,若front=last,表 ...

  9. CCS v5 无法启动解决办法及Launchpad仿真器电脑无法识别解决方法

    安装ccs_setup_5.1.1.00028.exe后(无论是自己装eclipse还是在原来的基础上安装eclipse的插件),ccs5的应用无法打开,错误为:An error has occurr ...

  10. 整合 新浪 腾讯 人人 qq空间 分享地址

    function snsShare(snsId, title, content, image, url) { var snsUrl; // 新浪 腾讯 要申请appkey switch (snsId) ...