大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > ASP.NET技巧 > 博客园头像上传源码全

博客园头像上传源码全

关键词:头像上传博客园源码  阅读(797) 赞(13)

[摘要]本文是对博客园头像上传源码的讲解,对学习ASP.NET编程技术有所帮助,与大家分享。

1、首先图片上传是一般网站都需要的,所以有必要自己整一个。

2、比较了好几个网站的图片上传功能,感觉博客园的比较好实现

3、看了下脚本,选用的是fineuploader+Jcrop,这个大家自己下吧,这里就不提供网址了。

4、效果图:

5、功能很简单,主要是预览,裁剪,保存,这样的插件有很多,但是本人没有选swf的,原因大家都知道。

6、重点和难点,由于fineuploader不兼容ie10以下版本,所以你会发现在ie8这个插件根本没办法执行,但是博客园却实现了上传功能,所以我坚信有解决办法(困扰我很久的问题)

不多说,直接上代码了。

感谢MVC版上传功能(这个版本有些问题,所以这个只能学习用。)

下面是修正的asp.net webform版本(已解决博客园在ie下重复上传出现失败的情况)

CSS

.qq-uploader {
    position: relative;
    width: 100%;
}
.qq-upload-button {
    display: block;
    /*or inline-block*/
    width: 105px;
    padding: 7px 0;
    text-align: center;
    background: #880000;
    border-bottom: 1px solid #DDD;
    color: #FFF;
}
.qq-upload-button-hover {
    background: #CC0000;
}
.qq-upload-button-focus {
    outline: 1px dotted #000000;
}
.qq-upload-drop-area, .qq-upload-extra-drop-area {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    min-height: 30px;
    z-index: 2;
    background: #FF9797;
    text-align: center;
}
.qq-upload-drop-area span {
    display: block;
    position: absolute;
    top: 50%;
    width: 100%;
    margin-top: -8px;
    font-size: 16px;
}
.qq-upload-extra-drop-area {
    position: relative;
    margin-top: 50px;
    font-size: 16px;
    padding-top: 30px;
    height: 20px;
    min-height: 40px;
}
.qq-upload-drop-area-active {
    background: #FF7171;
}
.qq-upload-list {
    margin: 0;
    padding: 0;
    list-style: none;
}
.qq-upload-list li {
    margin: 0;
    padding: 9px;
    line-height: 15px;
    font-size: 16px;
    background-color: #FFF0BD;
}
.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-retry, .qq-upload-failed-text, .qq-upload-finished {
    margin-right: 12px;
}
.qq-upload-file {
}
.qq-upload-spinner {
    display: inline-block;
    background: url("loading.gif");
    width: 15px;
    height: 15px;
    vertical-align: text-bottom;
}
.qq-upload-finished {
    display:none;
    width:15px;
    height:15px;
    vertical-align:text-bottom;
}
.qq-upload-retry {
    display: none;
    color: #000000;
}
.qq-upload-cancel {
    color: #000000;
}
.qq-upload-retryable .qq-upload-retry {
    display: inline;
}
.qq-upload-size, .qq-upload-cancel, .qq-upload-retry {
    font-size: 12px;
    font-weight: normal;
}
.qq-upload-failed-text {
    display: none;
    font-style: italic;
    font-weight: bold;
}
.qq-upload-failed-icon {
    display:none;
    width:15px;
    height:15px;
    vertical-align:text-bottom;
}
.qq-upload-fail .qq-upload-failed-text {
    display: inline;
}
.qq-upload-retrying .qq-upload-failed-text {
    display: inline;
    color: #D60000;
}
.qq-upload-list li.qq-upload-success {
    background-color: #5DA30C;
    color: #FFFFFF;
}
.qq-upload-list li.qq-upload-fail {
    background-color: #D60000;
    color: #FFFFFF;
}
.qq-progress-bar {
    background: -moz-linear-gradient(top,  rgba(30,87,153,1) 0%, rgba(41,137,216,1) 50%, rgba(32,124,202,1) 51%, rgba(125,185,232,1) 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(30,87,153,1)), color-stop(50%,rgba(41,137,216,1)), color-stop(51%,rgba(32,124,202,1)), color-stop(100%,rgba(125,185,232,1))); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* IE10+ */
    background: linear-gradient(to bottom,  rgba(30,87,153,1) 0%,rgba(41,137,216,1) 50%,rgba(32,124,202,1) 51%,rgba(125,185,232,1) 100%); /* W3C */
    width: 0%;
    height: 15px;
    border-radius: 6px;
    margin-bottom: 3px;
    display: none;
}
/*自定义样式*/
body {
    font-size: 12px;
    font-family: Verdana,Arial,Helvetica,sans-serif;
    margin: 0;
    padding: 10px;
    background: none repeat scroll 0 0;
}
li.alert-success {
    background-color: #DFF0D8;
}

li.alert-error {
    background-color: #F2DEDE;
}
[class*="span"] {
    float: left;
    min-height: 1px;
    margin-left: 20px
}
[class^="icon-"],[class*=" icon-"] {
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-top: 1px;
    line-height: 14px;
    vertical-align: text-top;
    background-image: url("../themes/icons/glyphicons-halflings-white.png");
    background-position:-144px -24px;
    background-repeat: no-repeat
}
.btn {
    display: inline-block;
    padding: 4px 12px;
    margin-bottom: 0;
    font-size: 14px;
    line-height: 20px;
    color: #333;
    text-align: center;
    text-shadow: 0 1px 1px rgba(255,255,255,0.75);
    vertical-align: middle;
    cursor: pointer;
    background-color: #f5f5f5;
    background-image: -moz-linear-gradient(top,#fff,#e6e6e6);
    background-image: -webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));
    background-image: -webkit-linear-gradient(top,#fff,#e6e6e6);
    background-image: -o-linear-gradient(top,#fff,#e6e6e6);
    background-image: linear-gradient(to bottom,#fff,#e6e6e6);
    background-repeat: repeat-x;
    border: 1px solid #bbb;
    border-color: #e6e6e6 #e6e6e6 #bfbfbf;
    border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);
    border-bottom-color: #a2a2a2;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px;
    filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);
    filter: progid: DXImageTransform.Microsoft.gradient(enabled=false);
    -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);
    -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)
}
.btn-success {
    color: #fff;
    text-shadow: 0 -1px 0 rgba(0,0,0,0.25);
    background-color: #5bb75b;
    background-image: -moz-linear-gradient(top,#62c462,#51a351);
    background-image: -webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));
    background-image: -webkit-linear-gradient(top,#62c462,#51a351);
    background-image: -o-linear-gradient(top,#62c462,#51a351);
    background-image: linear-gradient(to bottom,#62c462,#51a351);
    background-repeat: repeat-x;
    border-color: #51a351 #51a351 #387038;
    border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);
    filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);
    filter: progid: DXImageTransform.Microsoft.gradient(enabled=false)
}
.alert {
    padding: 8px 35px 8px 14px;
    margin-bottom: 20px;
    text-shadow: 0 1px 0 rgba(255,255,255,0.5);
    background-color: #fcf8e3;
    border: 1px solid #fbeed5;
    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    border-radius: 4px
}
.container {
    width: auto
}
.span12 {
    width: 80%
}

HTML

<body>
<div id="jquery-wrapped-fine-uploader"></div>
<div style="clear:both"></div>
<div id="message"></div>
<div id="crop_wrap">
        <div id="crop_holder">
                <div id="crop_area" >
                     <img id="crop_image" alt="" src=""  style="display:none" /></div>
                <div id="preview_area">
                        <div id="preview_title"> 当前头像 </div>
                        <div id="preview_small_text" class="preview-text"> 48px &times; 48px </div>
                        <div id="preview_small_wrap" class="border">
                             <img id="preview_small" alt="" src="../images/man.gif" class="preview-image" />
                        </div>
                        <div id="preview_large_text" class="preview-text">180px &times; 180px </div>
                        <div id="preview_large_wrap" class="border">
                            <img id="preview_large" alt="" src="../images/man.gif" class="preview-image" />
                        </div>
                </div>
        </div>
        <div id="crop_operation" style="display:none;">
                <form id="form_crop" action="">
                        <input type="hidden" name="x" id="x" />
                        <input type="hidden" name="y" id="y" />
                        <input type="hidden" name="w" id="w" />
                        <input type="hidden" name="h" id="h" />
                        <input type="hidden" name="imgsrc" id="imgsrc" />
                        <input id="crop_operation_submit" type="button" value="裁切并保存" />
                        <span id="crop_operation_msg" style="display:none" class="green"></span>
                </form>
        </div>
        <div id="croped_message" class="green"></div>
</div>
</body>

主要JS

function updateCoords(n) {
    jQuery("#x").val(n.x),
    jQuery("#y").val(n.y),
    jQuery("#w").val(n.w),
    jQuery("#h").val(n.h)
}
var croper;
$(function () {
    new Uploader($("#jquery-wrapped-fine-uploader"),
    function (n) {
        $("#preview_title").html("头像预览"),
        $("img.preview-image").each(function () {
            this.src = n
        }),
        $("#imgsrc").val(n),
        croper ? croper.setImage(n) : croper = new Croper($("#crop_image"), new Previewer([[$("#preview_small"), 48], [$("#preview_large"), 180]])),
        //防止重复添加click事件
        $("#crop_operation_submit").unbind("click");
        $("#crop_operation_submit").bind("click",
        function () {
            $("#crop_operation_msg").html("操作中...").show();
            //保存
            $.ajax({
                type: "POST",
                url: "../JsonData/UploadHandler.aspx?action=save&" + $('#form_crop').serialize().replace(/\+/g, " "),
                cache: false,
                error: function () { alert('执行失败.', 'warning'); },
                success: function (obj) {
                    n = eval(obj);
                    $("#crop_image").attr("src", "");
                    croper.setImage(""),
                    $("#preview_small").removeAttr("style").attr("src", n.FaceSrc);
                    $("#preview_large").removeAttr("style").attr("src", n.AvatarSrc);
                    $("#crop_operation").hide();
                    $("#crop_operation_msg").html("");
                    $("#croped_message").html("裁切并保存成功");
                    $("#preview_title").html("更新后的头像");
                }
            });
        }),
        $("#crop_operation").show(),
        $("#croped_message").html("")
    });
})
var Uploader = function () {
    var n = function (n, t) {
        n.fineUploader({
            validation: {
                allowedExtensions: ["png", "gif", "jpg", "jpeg"],
                sizeLimit: 10485760
            },
            request: {
                endpoint: "../JsonData/UploadHandler.aspx?action=upload"
            },
            text: {
                uploadButton: '<i ><\/i> 上传头像图片',
                dropProcessing: "(支持文件拖放上传,只能上传单张10M以下png、jpg、gif图片)"
            },
            template: '<div class="qq-uploader span12"><pre class="qq-upload-drop-area span12"><span>{dragZoneText}<\/span><\/pre><div class="qq-upload-button btn btn-success" style="width: auto;">{uploadButtonText}<\/div><span class="qq-drop-processing"><span>{dropProcessingText}<\/span><span class="qq-drop-processing-spinner"><\/span><\/span><ul class="qq-upload-list" style="margin-top: 10px;overflow:hidden;"><\/ul><\/div>',
            classes: {
                success: "alert alert-success",
                fail: "alert alert-error"
            },
            multiple: !1
        }).on("complete", function (n, i, r, u) {
            if (u.success) {
                var f = u.message;
                f += "?id=" + (new Date).getTime() + Math.floor(Math.random() * 1e3);
                t(f);
            }
            else
                $("#message").html(u.message)
        })
    };
    //裁剪计算方法.
    return n.prototype = { constructor: n }, n} (),
    Previewer = function () {
        var n, t = function (t) {
            n = t
        };
        return t.prototype = {
            constructor: t,
            showAllPreview: function (t) {
                var i = this.getWidgetSize(),
                    r;
                width = i[0], height = i[1], r = function (n, t, i) {
                    if (parseInt(n.w) > 0) {
                        var r = i / n.w,
                            u = i / n.h;
                        t.css({
                            width: Math.round(r * width) + "px",
                            height: Math.round(u * height) + "px",
                            marginLeft: "-" + Math.round(r * n.x) + "px",
                            marginTop: "-" + Math.round(u * n.y) + "px"
                        }).show()
                    }
                }, $.each(n, function () {
                    r(t, this[0], this[1])
                })
            },
            hideAllPreview: function () {
                $.each(n, function () {
                    this[0].stop().fadeOut("fast")
                })
            }
        }, t
    }(),
    Croper = function () {
        var n, t, i = function (i, r) {
            t = this, i.Jcrop({
                onChange: r.showAllPreview,
                onSelect: updateCoords,
                aspectRatio: 1
            }, function () {
                n = this, t.setSelect()
            })
        };
        return i.prototype = {
            constructor: i,
            setImage: function (i) {
                n.setImage(i, function () {
                    t.setSelect()
                })
            },
            setSelect: function () {
                var t = Math.min.apply(Math, n.getWidgetSize());
                n.setSelect([0, 0, t, t])
            }
        }, i
    }();

一般处理程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Drawing;

public partial class JsonData_UploadHandler : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string action = Request.QueryString["action"];
        switch (action)
        {
            case "upload":
                string qqfile = Request["qqfile"];
                var inputStream = Request.InputStream;
                if (string.IsNullOrEmpty(qqfile))
                {
                    //ie浏览器
                    HttpPostedFileBase file = new HttpPostedFileWrapper(HttpContext.Current.Request.Files[0]);
                    qqfile = file.FileName;
                    inputStream = file.InputStream;
                }
                string uploadFolder = "../UploadFile/TempImg/" + DateTime.Now.ToString("yyyyMM") + "/";
                string imgName = DateTime.Now.ToString("ddHHmmssff");
                string imgType = qqfile.Substring(qqfile.LastIndexOf("."));
                string uploadPath = Server.MapPath(uploadFolder);
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }
                using (var flieStream = new FileStream(uploadPath + imgName + imgType, FileMode.Create))
                {
                    inputStream.CopyTo(flieStream);
                }
                inputStream.Dispose();
                string json = "{\"success\":true,\"message\":\"" + uploadFolder + imgName + imgType + "\"}";
                Response.Write(json);
                break;
            case "save":
                int x = Convert.ToInt32(Request["x"]);
                int y = Convert.ToInt32(Request["y"]);
                int w = Convert.ToInt32(Request["w"]);
                int h = Convert.ToInt32(Request["h"]);
                string imgsrc = Request["imgsrc"].Substring(0, Request["imgsrc"].LastIndexOf("?"));
                string path = "({\"FaceSrc\":\"" + CropImage.CutImage(imgsrc, x, y, w, h, 48, 48, "_1") + "\","
                            + "\"AvatarSrc\":\"" + CropImage.CutImage(imgsrc, x, y, w, h, 180, 180, "_2") + "\"})";
                Response.Write(path);
                break;
            default:
                Response.Write("参数无效.");
                break;
        }
        Response.End();
    }
}

图片切割类

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;

public class CropImage
{
    /// <summary>
    /// 剪裁头像图片
    /// </summary>
    /// <param name="pointX">X坐标</param>
    /// <param name="pointY">Y坐标</param>
    /// <param name="imgUrl">被截图图片地址</param>
    /// <param name="rlSize">截图矩形的大小</param>
    public static string CutImage(string imgUrl, int pointX = 0, int pointY = 0, int width = 0, int height = 0, int finalWidth = 180, int finalHeight = 180, string suffix = "")
    {
        Bitmap bitmap = null;   //按截图区域生成Bitmap
        Image thumbImg = null;  //被截图 
        Graphics gps = null;    //存绘图对象   
        Image finalImg = null;  //最终图片
        try
        {
            if (!string.IsNullOrEmpty(imgUrl))
            {
                bitmap = new Bitmap(width, height);
                thumbImg = Image.FromFile(HttpContext.Current.Server.MapPath(imgUrl));
                gps = Graphics.FromImage(bitmap);      //读到绘图对象
                gps.DrawImage(thumbImg, new Rectangle(0, 0, width, height), new Rectangle(pointX, pointY, width, height), GraphicsUnit.Pixel);
                finalImg = GetThumbNailImage(bitmap, finalWidth, finalHeight);
                //以下代码为保存图片时,设置压缩质量  
                EncoderParameters ep = new EncoderParameters();
                long[] qy = new long[1];
                qy[0] = 80;//设置压缩的比例1-100  
                EncoderParameter eParam = new EncoderParameter(Encoder.Quality, qy);
                ep.Param[0] = eParam;

                ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo jpegICIinfo = null;
                for (int x = 0; x < arrayICI.Length; x++)
                {
                    if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    {
                        jpegICIinfo = arrayICI[x];
                        break;
                    }
                }
                string finalUrl = imgUrl.Replace("TempImg", "HeaderImg");
                finalUrl = finalUrl.Replace(".jpg", suffix + ".jpg");
                string finalPath = HttpContext.Current.Server.MapPath(finalUrl);
                string finalPathDir = finalPath.Substring(0, finalPath.LastIndexOf("\\"));
                if (!Directory.Exists(finalPathDir))
                {
                    Directory.CreateDirectory(finalPathDir);
                }
                if (jpegICIinfo != null)
                {
                    finalImg.Save(finalPath, jpegICIinfo, ep);
                }
                else
                {
                    finalImg.Save(finalPath);
                }
                return finalUrl;
            }
            return "";
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            bitmap.Dispose();
            thumbImg.Dispose();
            gps.Dispose();
            finalImg.Dispose();
            GC.Collect();
        }
    }

    ///<summary>
    /// 对给定的一个图片(Image对象)生成一个指定大小的缩略图。
    ///</summary>
    ///<param name="originalImage">原始图片</param>
    ///<param name="thumMaxWidth">缩略图的宽度</param>
    ///<param name="thumMaxHeight">缩略图的高度</param>
    ///<returns>返回缩略图的Image对象</returns>
    public static Image GetThumbNailImage(Image originalImage, int thumMaxWidth, int thumMaxHeight)
    {
        Size thumRealSize = Size.Empty;
        Image newImage = originalImage;
        Graphics graphics = null;
        try
        {
            //thumRealSize = GetNewSize(thumMaxWidth, thumMaxHeight, originalImage.Width, originalImage.Height);
            thumRealSize = new Size(thumMaxWidth, thumMaxHeight);
            newImage = new Bitmap(thumRealSize.Width, thumRealSize.Height);
            graphics = Graphics.FromImage(newImage);
            graphics.DrawImage(originalImage, new Rectangle(0, 0, thumRealSize.Width, thumRealSize.Height), new Rectangle(0, 0, originalImage.Width, originalImage.Height), GraphicsUnit.Pixel);
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (graphics != null)
            {
                graphics.Dispose();
                graphics = null;
            }
        }
        return newImage;
    }

    ///<summary>
    /// 获取一个图片按等比例缩小后的大小。
    ///</summary>
    ///<param name="maxWidth">需要缩小到的宽度</param>
    ///<param name="maxHeight">需要缩小到的高度</param>
    ///<param name="imageOriginalWidth">图片的原始宽度</param>
    ///<param name="imageOriginalHeight">图片的原始高度</param>
    ///<returns>返回图片按等比例缩小后的实际大小</returns>
    public static Size GetNewSize(int maxWidth, int maxHeight, int imageOriginalWidth, int imageOriginalHeight)
    {
        double w = 0.0;
        double h = 0.0;
        double sw = Convert.ToDouble(imageOriginalWidth);
        double sh = Convert.ToDouble(imageOriginalHeight);
        double mw = Convert.ToDouble(maxWidth);
        double mh = Convert.ToDouble(maxHeight);
        if (sw < mw && sh < mh)
        {
            w = sw;
            h = sh;
        }
        else if ((sw / sh) > (mw / mh))
        {
            w = maxWidth;
            h = (w * sh) / sw;
        }
        else
        {
            h = maxHeight;
            w = (h * sw) / sh;
        }
        return new Size(Convert.ToInt32(w), Convert.ToInt32(h));
    }
}

按钮图片(需要的话与本人联系,是博客园的原图)

测试环境,chrome,ie8,360



相关评论