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常用属性

uploader

uploadify的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()});  //更新参数

<%@ 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)

<%@ 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)

<%@ 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 :这是上传速度

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jerry的SAP技术分享

SAP CRM和C4C的产品主数据price维护

/sap/ap/ui/json?app.component=/BYD_COD/SalesOnDemand/Product/UI/COD_Material.TI....

15570
来自专栏跟着阿笨一起玩NET

EPPlus与Excel完美的结合

笔者近期在公司项目中需要生产比较复杂的Excel报表, 问题点是单个Excel文件中必须能包含多个sheet, 按照以前项目的经验, 此情况需要使用MS Off...

36410
来自专栏hotqin888的专栏

电子规范管理系统standardms在linux系统中部署遇到的坑

局域网内用一台闲置的电脑,安装了linux,部署了engineercms,docker和onlyoffice进行项目管理、文档协作,还缺少一利器:电子规范管理。...

9830
来自专栏.NET开发者社区

一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](四)

上一篇《一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](三)》,我们完成了:

23090
来自专栏一只程序汪的自我修养

手把手教你用.NET Core写爬虫

19520
来自专栏大内老A

如何通过自定义MessageFilter的方式利用按键方式操作控件滚动条[附源代码]

很长一段时间内,一直在做一个SCSF(Smart Client Software Factory)的项目,已经进入UAT阶段。最近,用户提出了一个要求:需要通过...

31370
来自专栏跟着阿笨一起玩NET

【C#】工具类-FTP操作封装类FTPHelper

转载:http://blog.csdn.net/gdjlc/article/details/11968477

29710
来自专栏菩提树下的杨过

利用message queue实现aspx与winform通信, 并附完整示例

先在本机(本文中的计算机名为jimmyibm)安装message queue(消息队列),别告诉我你不会安装.(就跟安装IIS差不多的) 安装好后,打开 "计算...

29480
来自专栏程序员的SOD蜜

常见.NET功能代码汇总

1,在Web上修改指定文件位置的Web.config 这里需要使用 WebConfigurationManager 类,但必须使用WebConfiguratio...

459100
来自专栏听雨堂

【6】页面数据和控件的自动交换机制

阅读目录 数据维护通用流程 数据的加载 数据的修改 数据的添加 自动交换机制 使用PageX来完成数据的自动加载 非标准数据的处理 只要...

24680

扫码关注云+社区

领取腾讯云代金券