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

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

Step 1 选择上传照片

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

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

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

来看下代码吧

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

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

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

因为我们点击的时候,因为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({ width: currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
    $imagedrag.css({ width: 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({ width: currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
          imagedrag.css({ width: 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({ width: currentWidth + "px", height: currentHeight + "px", left: originLeft + "px", top: originTop + "px" });
        imagedrag.css({ width: 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;
        }
       
    }

Jquery+ASP.NET 实现开心网上传头像剪裁功能[转]相关推荐

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

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

  2. 圆角头像剪裁php,PHP与JS实现头像剪裁功能架构总结

    准备开发个头像上传及剪裁功能 想象的比较简单 没想到做起来这么费时间 – – 逻辑也要比我想象的多 下面简单说一下前后端的实现! 前端:主要是用JS 这里如果想偷懒的话推荐两个JQ jcrop和jsc ...

  3. vue 移动端头像裁剪_移动端 上传头像 并裁剪功能(h5)

    移动端头像图片上传裁剪 .button { outline: 0; display: inline-block; margin-bottom: 0; font-weight: 400; text-al ...

  4. jQuery 自制上传头像插件-附带Demo实例(ajaxfileupload.js第三弹)

    这篇文章主要是对前两篇关于ajaxfileupload.js插件的文章 <ASP.NET 使用ajaxfileupload.js插件出现上传较大文件失败的解决方法(ajaxfileupload. ...

  5. ajax图片上传插件demo,jQuery 自制上传头像插件-附带Demo实例(ajaxfileupload.js第三弹)...

    这篇文章主要是对前两篇关于ajaxfileupload.js插件的文章 的一个收关.但是最初也是因为想做这么一个功能,一点一点的引发出了好多问题,不断去学习,研究,才写了这三篇. 早些时候已经实现了上 ...

  6. 完美实现类似QQ的自拍头像、上传头像功能!(Demo 源码)

    现在很多下载客户端程序都需要设定自己头像的功能,而设定头像一般有两种方式:使用摄像头自拍头像,或者选择一个图片的某部分区域作为自己的头像. 一.相关技术 若要实现上述的自拍头像和上传头像的功能,会碰到 ...

  7. 小程序上传头像图片裁剪

    原文链接:https://blog.csdn.net/qq_41049816/article/details/90604607* 给网上收到的 不知道好不好用 先收藏着: 小程序涉及到了用户上传头像的 ...

  8. php更换wordpress用户头像,WordPress如何添加用户自定义上传头像功能

    使用WordPress建站的朋友应该知道,WordPress本身是没有上传自定义头像功能的,如果要更换头像,步骤是非常麻烦的. 而在我们开发一款WordPress主题中,特别是多用户的主题,让注册用户 ...

  9. 关于注册页面上传头像并在后台处理数据

    之前在做注册页面头像上传时,发现直接通过request.getParameter方法获取到的值全是null,后面经过查找资料找出了原因,因为在普通注册页面的基础上加入了上传头像的功能,所以需要在for ...

最新文章

  1. 鼠标控制,扇形的大小
  2. 深入理解 Flutter 的编译原理与优化
  3. SQL Server Error 15404解决方案
  4. C++的const限定符
  5. 一个小白如何创建MYSQL数据表_MySQL小白扫盲(二)--建表、添加、查询
  6. Spark源码阅读@ListenerBus 的实现
  7. 哈工大网络安全实验五报告
  8. 易基因|文献科普:MeRIP-seq揭示m6A RNA甲基化改变导致亨廷顿病(HD)小鼠海马记忆障碍
  9. 【渝粤题库】陕西师范大学209020 史记研究 作业(专升本)
  10. 链家网页爬虫_爬虫小技巧——以最简单的方式爬取链家房源信息
  11. 理解一下什么是全栈工程师
  12. bigworld源码分析(3)——dbMgr分析
  13. [Linux Audio Driver] Qualcomm平台音频GMS认证器件要求
  14. 中文字符 简体繁体相互转换
  15. 小米路由器忘记管理密码后重置密码
  16. 11 如何成为可转债的交易好手
  17. 想学CNC编程的一定要看过来~
  18. android 存储盘 dcim,DCIM是什么?教你轻松理清照片存放路径
  19. [转贴]去除迅雷广告和弹出广告窗口
  20. 20155227辜彦霖《基于Cortex-M4的UCOSIII的应用》课程设计个人报告

热门文章

  1. 线程中断机制 interrupt、isInterrupted、interrupted方法
  2. POJ3704 括号匹配问题
  3. 阿里资深架构师——支付宝和蚂蚁花呗的技术架构及双十一实践
  4. iOS 微信支付 上架被拒
  5. 带带弟弟ocr,对各种类型验证码说不!
  6. RHCE(一)--- at、crontab、网卡绑定
  7. iPhone上关于相机拍照的图片反转90度的问题
  8. Apollo 11号登月飞船制导计算机源代码(待续)
  9. linux 进入编辑文件,保存退出相关命令
  10. 【HEC-RAS】模型不稳定故障排除技巧(一)