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下载地址

  • 相关阅读:
    测试
    Python 学习笔记【15】文件操作
    Python 学习笔记【14】集合
    Python 学习笔记【13】练习:三级菜单
    Python 学习笔记【12】字典
    Python 学习笔记【11】字符串操作
    Python 学习笔记【10】练习:购物车程序
    Python 学习笔记【09】列表、元组
    Python 学习笔记【08】数据类型、数据运算、进制转换
    Python 学习笔记【07】PEP 8 中英对照
  • 原文地址:https://www.cnblogs.com/kissdodog/p/2827867.html
Copyright © 2011-2022 走看看