首页 > 代码库 > jQuery之Jcrop

jQuery之Jcrop

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

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="http://www.mamicode.com/上传" />        <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="http://www.mamicode.com/0" />        <input type="hidden" id="y1" name="y1" value="http://www.mamicode.com/0" />        <input type="hidden" id="cw" name="cw" value="http://www.mamicode.com/0" />        <input type="hidden" id="ch" name="ch" value="http://www.mamicode.com/0" />        <input type="submit" value="http://www.mamicode.com/裁剪上传" />    </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下载地址