zoukankan      html  css  js  c++  java
  • 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()});  //更新参数

    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; //最终图片

    if (HttpContext.Current.Session["UploadSession"] != 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;
    }
    }
    else
    {
    context.Response.Write("erorr");
    }
    }

    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下载:https://files.cnblogs.com/zhongweiv/CutAvatar.rar

  • 相关阅读:
    出现过拟合与欠拟合的原因以及解决方案
    Oracle数据库连接生成DDL
    CentOS 7 安装 maven
    基于Spring mvc 的Websocket 开发
    HttpComponents之httpclient
    java filter 实现权限控制
    java hasmap对象的深复制实现:字节码复制和对象序列化成字符串复制比较。
    eatwhatApp开发实战(二)
    eatwhatApp开发实战(一)
    [安卓安全] 01.安卓本地数据存储:Shared Preferences安全风险浅析
  • 原文地址:https://www.cnblogs.com/wichell/p/2267665.html
Copyright © 2011-2022 走看看