专栏首页Porschev[钟慰]的专栏Asp.Net无刷新上传并裁剪头像

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 条评论
登录 后参与评论

相关文章

  • 一个例子理解C#位移

    很多人提问,不知道C#位移,可能有些人在面试中也遇到过 其实很简单。。。 C#位移运算符: 左移:<< 右移:>> 位移理解可能简单一些:其实就是数据转换成二进...

    Porschev
  • 前台JS(Jquery)调用后台方法 无刷新级联菜单示例

    前台用AJAX直接调用后台方法,老有人发帖提问,没事做个示例 CasMenu.aspx页面: <%@ Page Language="C#" AutoEventW...

    Porschev
  • Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

    前言   前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子   上传功能命名用formidabl...

    Porschev
  • LogDevice:一种用于日志的分布式数据存储系统

    说到日志,它就是一个将有序序列的不可变记录记下来,并将此记录可靠地保存下来的最简单的方法。如果想要构建一套数据密集型分布式服务,你可能需要一两套日志。在Face...

    山月
  • Java Review(三十三、异常处理----补充:断言、日志、调试)

    断言(Assertion)是一种调试程序的方式。在Java中,使用assert关键字来实现断言。

    三分恶
  • python-troveclient源代

    client.Client返回值为troveclient.v1.client.Client(option.os_database_api_version, .....

    py3study
  • 超強统计插件:My Visitors在知更鸟主题下的修改教程

    这款插件是今天在研究互推联盟页面在荣誉站点的点击率统计时发现的,感觉非常给力,一个顶四! 先来几张截图: 全部功能菜单: ? 非常详细的访客清单,还可...

    张戈
  • MySQL 那些监控参数 问 答 (4)REDO AHI latch 锁

    2020已经悄然来到身边,感觉时间过的很快,学习的过程也是,一阵热乎的很简单,难再坚持两个字好写,做起来确实是难事。本系列后续还会有,会因为监控这个事情本身就没...

    AustinDatabases
  • day15-python之变量和递归

    py3study
  • 火焰图性能调优记

    最近手头开发维护的一个辅助小工具经常接到投诉可用性问题, 于是抽时间定位了下, 一看吓一跳, 起初不起眼的一个组件的日志量直接翻了两个数量级。 这怎么吃得消 !

    黄奕坤

扫码关注云+社区

领取腾讯云代金券