zoukankan      html  css  js  c++  java
  • 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="上传" />
            <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下载地址

  • 相关阅读:
    Good Bye 2014 B. New Year Permutation(floyd )
    hdu 5147 Sequence II (树状数组 求逆序数)
    POJ 1696 Space Ant (极角排序)
    POJ 2398 Toy Storage (叉积判断点和线段的关系)
    hdu 2897 邂逅明下 (简单巴什博弈)
    poj 1410 Intersection (判断线段与矩形相交 判线段相交)
    HDU 3400 Line belt (三分嵌套)
    Codeforces Round #279 (Div. 2) C. Hacking Cypher (大数取余)
    Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
    hdu 1576 A/B (求逆元)
  • 原文地址:https://www.cnblogs.com/feng-NET/p/4541073.html
Copyright © 2011-2022 走看看