• [转]也说 Jquery+ASP.NET 实现开心网上传头像剪裁功能


    http://www.cnblogs.com/xuanye/archive/2008/09/25/1299091.html

    前几天博客园cnblogs里有个朋友发了一个类似的帖子(你可以点这里查看),刚刚也要做这个功能,但是原来程序稍微有点问题,特别在前台上有几处不合理的地方,所以就着开心网的代码重写一下,效果如下

    Step 1 选择上传照片

    image 

    Step2 ,点击上传一张图片,默认缩放到刚好填充画布,如果图片小于画布就不缩放了,并且将图片集中

    image

    缩放图片是,以画布中的选取框为中,向四周扩散,缩小

    image

    点击保存按钮 保存截取后的图片

    image 

    来看下代码吧

    前台:需要引用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片段

    image

    2:这个是开心网中的html片段

    image

    开心网中用一个table作为画布的架子,中间的一个td设置样式为选取框,把img移到table下面,就可以看到上图的效果了,但是在设置drap的时候handler设置为table(id=crop),来看下下面开心网的代码就知道了。

    image

    因 为我们点击的时候,因为table在img之上,所以点击只能点到table。但是Jquery的drap handle不能设置源以外的元素,所以上面的方法就行不通了,参考了原文中的做法,用两个图片代替,一个做成蒙层的效果 (ImageDragContainer),一个缩小放到中间的位置,变成剪切窗口(IconContainer),只要控制好两个图片的 left,top,width,height,那么可以做到看上去像一个图片那样。如前面的效果所示。

    其他html就是一些布局,上传控件和几个用于存放值的textbox了,就不介绍了,来看下js把,关键的,都加上注释了。有问题可以留言交流

    /// <reference path="JSintellisense/jquery-1.2.6-intellisense.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({ currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
        $imagedrag.css({ 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({ currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
              imagedrag.css({ 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({ currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
            imagedrag.css({ 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中的参数进行图片切割,也比较简单,来看下分为两个,一个是缩放裁剪,一个原图裁剪,代码参考原文。

     public static string SaveCutPic(string pPath, string pSavedPath, int pPartStartPointX, int pPartStartPointY, int pPartWidth, int pPartHeight, int pOrigStartPointX, int pOrigStartPointY, int imageWidth, int imageHeight)
            {
                 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;
            }
           
        }
  • 相关阅读:
    linux离线安装mysql
    SpringBoot配置SSL证书
    java在liunx下备份mysql数据,恢复数据
    Redis的缓存穿透,缓存击穿,缓存雪崩
    Spring缓存注解
    Advanced Algorithm Scripting
    Arguments Optional
    Everything Be True
    Binary Agents
    Steamroller
  • 原文地址:https://www.cnblogs.com/jt880807/p/2693591.html
Copyright © 2020-2023  润新知