Asp.Net无刷新上传并裁剪头像

开发网站几乎都做过上传图片并截图,做个无刷新Asp.Net上传并截图示例

实现功能:

1.选择文件,自动上传并生成缩放图(上传带进度条),形成预览图

2.在预览区,实现鼠标拖拽截图区,截取图片(示例截图区按缩放图小边为截图正方形长度,可扩展为截图区可变形式)

3.点击保存,截取小图,保存截取图并显示在页面上,并删除原缩略图

示例截图:

上传中

上传成功并截图

 

-------------------------------------------------------------------------------风骚分隔线-----------------------------------------------------------------------------------------------

 

第一步:准备工作,认识一些必要的东西 

 1.无刷新上传借助于Uploadify这个基于Flash的支持多文件上传的Jquery插件,很多人估计都用过了,我也在不同的项目中用过很多次,简单易用且功能强大

    (美中不足,插件本身对session使用有一点BUG,不过能解决,chrome&FireFox里上传如果代码中有用Session,获取不到)

 

没用过这个插件的可以去它的官网认识一下这个插件

Uploadify官网:  

  http://www.uploadify.com/

uploadify下载:  (本示例用:Uploadify-v2.1.4.zip

  http://www.uploadify.com/download/

uploady全属性、事件、方法介绍:

  http://www.uploadify.com/documentation/

 

这里对一些常用介绍一下:

名称介绍类型
Uploadify常用属性
uploaderuploadify的swf文件的路径string
cancelImg取消按钮图片路径string
folder上传文件夹路径string
multi是否多文件上传boolean
script上传文件处理代码的文件路径json
scriptData提交到script对应路径文件的参数类型
method提交scriptData的方式(get/post)string
fileExt支持上传文件类型(格式:*.jpg;*.png)string
fileDesc提示于点击上传弹出选择文件框文件类型(自定义)string
sizeLimit上传大小限制(byte为单位)integer
auto是否选择文件后自动上传boolean
Uploadify常用事件
onAllComplete上传完成后响应function
onCancel取消时响应function
Uploadify常用方法
.uploadify()初始化uploadify上传 
.uploadifyUpload()触发上传 
.uploadifySettings()更新uploadify的属性 

 

2.裁剪图片使用CutPic.js  (这个JS文件如果各位要用,要自己用心看看,注释很详细了)

   源码太长,这里不贴出来,后面会提供下载

   显示图片也用的CutPic里的方法

  JS代码显示

 function ShowImg(imagePath,imgWidth,imgHeight) {           
       var imgPath = imagePath != "" ? imagePath : "!images/ef_pic.jpg";           
       var ic = new ImgCropper("bgDiv", "dragDiv", imgPath, imgWidth, imgHeight, null);
 }

 HTML显示部分布局(一个嵌套层级关系,外面是显示图片,里面dragDiv是拖拽层)

 <div id="bgDiv">
          <div id="dragDiv">
          </div>
  </div>

 

 

第二步:引用资源,开始编写

 

Default.aspx页

用了三个隐藏域去存截图区的左上角X坐标,Y坐禁,以及截图框的大小;

这个要修改CutPic里设置切割要用到,CutPic.js里己经做了注释;

Uploadify中参数如果动态改变的,可以写在像我下面写的这样去更新参数

$("#uploadify").uploadifySettings('scriptData',{'LastImgUrl':$('#hidImageUrl').val()});  //更新参数

View Code
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Posrchev-裁剪头像</title>

    <script src="!js/jquery-1.4.1.min.js" type="text/javascript"></script>

    <script src="!js/cutpic.js" type="text/javascript"></script>

    <script src="!js/uploadify-v2.1.4/jquery.uploadify.v2.1.4.min.js" type="text/javascript"></script>

    <script src="!js/uploadify-v2.1.4/swfobject.js" type="text/javascript"></script>

    <link href="!css/Main.css" rel="stylesheet" type="text/css"/>
    
    <link href="!css/uploadify.css" rel="stylesheet" type="text/css"/>

    <script type="text/javascript"> 
        var imageWidth =300;
        var imageHeiht =300;
                
        $(function(){                                              
             $('#uploadify').uploadify({
                   'uploader': '/!js/uploadify-v2.1.4/uploadify.swf',
                  'script': '/Handler/UploadAvatarHandler.ashx',                              
                  'cancelImg': '/!js/uploadify-v2.1.4/cancel.png',
                  'folder'    : '/Temp',                            
                  'queueID': 'fileQueue',
                  'auto': true,
                  'multi': false,      
                  'method' : 'get',                      
                  'fileExt': '*.jpg;*.png',
                  'fileDesc': '请选择jpg , png文件...',                  
                  'scriptData': null,
                  'sizeLimit'   : 2097152,
                  'onComplete': function (event, queueID, fileObj, response, data) {
                     if (response.indexOf('Temp') !=-1) {
                                                                       
                         $("#bgDiv img").remove();                      //移除截图区里image标签
                         $("#btnSave").show();                          //保存按钮显示                    
var result = response.split('$');              //得返回参数
                         
                         var maxVal =0;                           
                         if(result[1] > result[2])
                         {
                            maxVal = result[2];                            
                         }
                         else
                         {
                            maxVal = result[1];
                         }                        
                         $("#maxVal").val(maxVal);                     //设置截图区大小
                         
                         $("#hidImageUrl").val(result[0]);             //上传路径存入隐藏域
                      
                         ShowImg(result[0],result[1],result[2]);       //在截图区显示
                         
                         $("#uploadify").uploadifySettings('scriptData',{'LastImgUrl':$('#hidImageUrl').val()});          //更新参数
                                                   
                     }
                     else {
                        alert(response);
                     }
                  }
             });    
             
             
             $("#btnSave").click(function(){                                       
                $.ajax({                    
                    type: "POST",                                   
                    url: "/Handler/CutAvatarHandler.ashx",                      
                    data: {imgUrl:$('#hidImageUrl').val(),pointX:$("#x").val(),pointY:$("#y").val(),maxVal:$("#maxVal").val()},                                                                                         
                    success: function(msg) {     
                        if (msg.indexOf('User') !=-1) {
                            $("#imgCut").attr("src",msg);     
                        }
                        else
                        {
                            alert("error");
                        }                                                                              
                    },                    
                    error: function(xhr, msg, e) {                        
                        alert("error");                    
                    }                
                 });     
             });                                                  
        });
        
        
                        
        function ShowImg(imagePath,imgWidth,imgHeight) {           
            var imgPath = imagePath !=""? imagePath : "!images/ef_pic.jpg";           
            var ic =new ImgCropper("bgDiv", "dragDiv", imgPath, imgWidth, imgHeight, null);
        }
         
         
        
        //{ Right: "rRight", Left: "rLeft", Up: "rUp", Down: "rDown", RightDown: "rRightDown", LeftDown: "rLeftDown", RightUp: "rRightUp", LeftUp: "rLeftUp"}
</script>

</head>
<body>
    <form id="form1" runat="server">
    <div class="fl avatarbg">
        <div class="avatarboxbar">
            <div id="bgDiv">
                <div id="dragDiv">
                </div>
            </div>
        </div>
    </div>
    <div class="avatarthumb">
        <asp:Image ID="imgCut" ImageUrl="/!images/blank_pic.jpg" runat="server"/>
    </div>
    <br />
    <div class="uploadimg">
        <div class="upload">
            <div class="uploadswf">
                <input type="file" name="uploadify" id="uploadify"/>
            </div>
            <br />
            <p id="fileQueue">
            </p>
        </div>
    </div>
    <input id="btnSave" type="button" value="保存" style="display: none;"/>
    <input id="x" runat="server" type="hidden" value="0"/>
    <input id="y" runat="server" type="hidden" value="0"/>
    <input id="hidImageUrl" type="hidden" value=""/>
    <input id="maxVal" runat="server" type="hidden" value="100"/>
    </form>
</body>
</html>

 

上传图片Hander代码(UploadAvatarHandler.ashx)

View Code
<%@ WebHandler Language="C#" Class="CutAvatarHandler" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.SessionState;
public class CutAvatarHandler : IHttpHandler, IRequiresSessionState
{

    [WebMethod(EnableSession = true)]
    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Charset = "utf-8";

        System.IO.Stream stream = null;
        System.Drawing.Image originalImg = null;   //原图
        System.Drawing.Image thumbImg = null;      //缩放图       


        try
        {
            int minWidth = 100;   //最小宽度
            int minHeight = 100;  //最小高度
            int maxWidth = 300;  //最大宽度
            int maxHeight = 300;  //最大高度

            string resultTip = string.Empty;  //返回信息

            HttpPostedFile file = context.Request.Files["Filedata"];      //上传文件      

            string uploadPath = HttpContext.Current.Server.MapPath(@context.Request["folder"]);  //得到上传路径

            string lastImgUrl = @context.Request.Params["LastImgUrl"];

            if (!string.IsNullOrEmpty(lastImgUrl))
            {
                PubClass.FileDel(HttpContext.Current.Server.MapPath(lastImgUrl));
            }

            if (file != null)
            {
                if (!System.IO.Directory.Exists(uploadPath))
                {
                    System.IO.Directory.CreateDirectory(uploadPath);
                }

                string ext = System.IO.Path.GetExtension(file.FileName).ToLower();   //上传文件的后缀(小写)

                if (ext == ".jpg" || ext == ".png")
                {
                    string flag = "ThumbNail" + DateTime.Now.ToFileTime() + ext;

                    string uploadFilePath = uploadPath + "\\" + flag;   //缩放图文件路径

                    stream = file.InputStream;

                    originalImg = System.Drawing.Image.FromStream(stream);

                    if (originalImg.Width > minWidth && originalImg.Height > minHeight)
                    {
                        thumbImg = PubClass.GetThumbNailImage(originalImg, maxWidth, maxHeight);  //按宽、高缩放

                        if (thumbImg.Width > minWidth && thumbImg.Height > minWidth)
                        {
                            thumbImg.Save(uploadFilePath);

                            resultTip = @context.Request["folder"] + "\\" + flag + "$" + thumbImg.Width + "$" + thumbImg.Height;
                        }
                        else
                        {
                            resultTip = "图片比例不符合要求";
                        }
                    }
                    else
                    {
                        resultTip = "图片尺寸必须大于" + minWidth + "*" + minHeight;
                    }
                }
            }
            else
            {
                resultTip = "上传文件为空";
            }

            context.Response.Write(resultTip);
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            if (originalImg != null)
            {
                originalImg.Dispose();
            }

            if (stream != null)
            {
                stream.Close();
                stream.Dispose();
            }

            if (thumbImg != null)
            {
                thumbImg.Dispose();
            }

            GC.Collect();
        }


    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}

 

切割图片Hander代码(CutAvatarHandler.ashx)

View Code
<%@ WebHandler Language="C#" Class="CutAvatarHandler" %>

using System;
using System.Web;
using System.Web.SessionState;

public class CutAvatarHandler : IHttpHandler, IRequiresSessionState
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        context.Response.Charset = "utf-8";

        System.Drawing.Bitmap bitmap = null;   //按截图区域生成Bitmap
        System.Drawing.Image thumbImg = null;      //被截图 
        System.Drawing.Graphics gps = null;    //存绘图对象   
        System.Drawing.Image finalImg = null;  //最终图片


        try
        {
            string pointX = context.Request.Params["pointX"];   //X坐标
            string pointY = context.Request.Params["pointY"];   //Y坐标
            string imgUrl = context.Request.Params["imgUrl"];   //被截图图片地址
            string rlSize = context.Request.Params["maxVal"];        //截图矩形的大小

            int finalWidth = 100;
            int finalHeight = 100;

            if (!string.IsNullOrEmpty(pointX) && !string.IsNullOrEmpty(pointY) && !string.IsNullOrEmpty(imgUrl))
            {

                string ext = System.IO.Path.GetExtension(imgUrl).ToLower();   //上传文件的后缀(小写)

                bitmap = new System.Drawing.Bitmap(Convert.ToInt32(rlSize), Convert.ToInt32(rlSize));

                thumbImg = System.Drawing.Image.FromFile(HttpContext.Current.Server.MapPath(imgUrl));

                System.Drawing.Rectangle rl = new System.Drawing.Rectangle(Convert.ToInt32(pointX), Convert.ToInt32(pointY), Convert.ToInt32(rlSize), Convert.ToInt32(rlSize));   //得到截图矩形

                gps = System.Drawing.Graphics.FromImage(bitmap);      //读到绘图对象

                gps.DrawImage(thumbImg, 0, 0, rl, System.Drawing.GraphicsUnit.Pixel);

                finalImg = PubClass.GetThumbNailImage(bitmap, finalWidth, finalHeight);

                string finalPath = "/User/final" + DateTime.Now.ToFileTime() + ext;

                finalImg.Save(HttpContext.Current.Server.MapPath(finalPath));

                bitmap.Dispose();
                thumbImg.Dispose();
                gps.Dispose();
                finalImg.Dispose();
                GC.Collect();

                PubClass.FileDel(HttpContext.Current.Server.MapPath(imgUrl));

                context.Response.Write(finalPath);
            }
        }
        catch (Exception)
        {
            throw;
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}



这种就可以达到我文章开头的要求了

 

第三步:修复文件开头提到Uploadify用Session在Chrome和FireFox下的Bug (身份验证也一样有这个BUG,修复同理)

如果UploadAvatarHandler.ashx中要用到Session那就需求些额外的配置

在Global.asax中Application_BeginRequest加入下列代码

复制代码
 protected void Application_BeginRequest(object sender, EventArgs e)
        {
            //为了Uploadify在谷歌和火狐下不能上传的BUG
            try
            {
                string session_param_name = "ASPSESSID";
                string session_cookie_name = "ASP.NET_SessionId";
                if (HttpContext.Current.Request.Form[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
                {
                    UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
                }             
            }
            catch
            {
            }

            //此处是身份验证
            try
            {
                string auth_param_name = "AUTHID";
                string auth_cookie_name = FormsAuthentication.FormsCookieName;
                if (HttpContext.Current.Request.Form[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
                }
                else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
                {
                    UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
                }
            }
            catch { }
        }
复制代码

 

页面中加入隐藏域

 <asp:HiddenField ID="hdSessionId" runat="server" />

并在页面的Load事件中,把SessionID赋给隐藏域


Uploadify()方法scriptData属性在做修改

$('#uploadify').uploadify({
      //....            
      'scriptData': { 'ASPSESSID': $('[id$=hdSessionId]').val() },
      //.....                
});    

 

以上操作,用于修改身份验证也一样。。。

 

 

第四步:一些扩展 

CutPic.js中有一些可以扩展

比如:有人要求截图区域自己要可以拖动

 

 

把CutPic.js图片显示,截图区HTML变成这样

复制代码
           <div id="bgDiv">
                <div id="dragDiv">
                    <div id="rRightDown" style="right: 0; bottom: 0;">
                    </div>
                    <div id="rLeftDown" style="left: 0; bottom: 0;">
                    </div>
                    <div id="rRightUp" style="right: 0; top: 0;">
                    </div>
                    <div id="rLeftUp" style="left: 0; top: 0;">
                    </div>
                    <div id="rRight" style="right: 0; top: 50%;">
                    </div>
                    <div id="rLeft" style="left: 0; top: 50%;">
                    </div>
                    <div id="rUp" style="top: 0; left: 50%;">
                    </div>
                    <div id="rDown" style="bottom: 0; left: 50%;">
                    </div>
                </div>
            </div>
复制代码

 

再给这些新添DIV写些样式。。。^_^!   这里自己扩展吧

显示区的JS加上最后一个参数

function ShowImg(imagePath,imgWidth,imgHeight) {           
       var imgPath = imagePath != "" ? imagePath : "!images/ef_pic.jpg";           
       var ic = new ImgCropper("bgDiv", "dragDiv", imgPath, imgWidth, imgHeight, { Right: "rRight", Left: "rLeft", Up: "rUp", Down: "rDown", RightDown: "rRightDown", LeftDown: "rLeftDown", RightUp: "rRightUp", LeftUp: "rLeftUp"});
 }

 

 

可能还有需求上传不要进度条,这个我没找到属性,有用过的可以指点一下,

不过这个问题没有属性也不是不可以解决的,可以在uploadify的JS文件中删除或注释掉append的这一段进度条HTML代码。

 

这样就做完了,Uploadify和这个CutPic.js几乎能做到所有现在能看到的上传截图功能,还有的自己扩展一下^-^!

 

PS:示例代码没有优化,请各位自己做做优化^_^!

 

Demo下载:VS08:     http://files.cnblogs.com/zhongweiv/CutAvatarVS08.rar

                VS10:      http://files.cnblogs.com/zhongweiv/CutAvatarVS10.rar

                (大家在看这个Demo时好像遇到不少问题,我帮大家转好了08和10的,各位可以下载,IIS的配置还是那样)

Demo友情提示:布署在IIS上,再看,因为示例路径全是从根目录开始

 

 

 

 

对于各位看官的疑问解答: 

 

-----------------------------------------------------------------------------------------------------------------------------------

1.Demo相关(因为个人习惯,写东西喜欢布暑在IIS中,路径从根目录开始,所以直接看,带来了些不便^_^!)

   

   如果没有显示出FLash上传的,那一定是路径有问题

   对于Demo再加些操作提示,可能很多人没有用过自定义端服务器:

 1.布暑在IIS里,设置好端口号,如果是4.0环境,应用程序连接池选择framework4.0

 2.在VS中设置,选中网站项目,右键---->属性页---->启动选项---->选择自定义服务器---->基URL填入你在IIS里设置的,比如:http://localhost:XXXX/           (XXXX代表你在IIS里设置的端口号)

   3.确实,运行页面

 

   如果用VS10转化,在IIS里布暑点击保存出来error

   那有两种可能
   1.连接池framework的版本你还是没选对
   2,ISAPI和GCI限制里asp.net4.0没有设置为允许。。。
   如果这个Demo会出错。。那你转成4.0之后编译应该就会报targetFramework的错。。。。如果实在没有什么IIS的设置经验,建议自己搜索一下或者看看IIS方面的文章

 

 

-----------------------------------------------------------------------------------------------------------------------------------

 

2.onComplete事件方法中几个参数的解释:

  event:名字就很明显了
  queueId 就是个唯一标识
  fileObj 这是指那个文件
    比如:fileObj.name 就是文件名
    fileObj.size 是文件大小
    上传文件的相关信息都可以用这个获得,还有创建时间,文件类型 等 
    response:这是你返回的信息
    data:有四个属性
  filesUploaded :上传了多少个文件
  errors :出现了多少个错误
  allBytesLoaded :总共上传文件的大小(因为它可以多文件上传)
  speed :这是上传速度

原文链接 :http://www.cnblogs.com/zhongweiv/archive/2011/11/29/2266544.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值