在项目中使用 Discuz!NT的上传头像功能

  大概半年前,由于某个网站项目需要整合Discuz!NT,就粗略的用了一下。觉得里面的会员上传头像功能方便好用,而且支持摄像头,就把它的代码分离出来,以后用在需要的地方。

  

  用过Discuz!NT的朋友会知道,这个上传头像功能有两个版本,一个是 Flash版,另一个是 Silverlight版,这次主要是关于 Flash版。

  要使用这个功能十分简单(最难地方才是那个Flash的代码)。

  使用页面 Default.aspx 代码

 

 

代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Avatar.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></title>
<script type="text/javascript">
function $(id) {
return document.getElementById(id);
}
var userAgent = navigator.userAgent.toLowerCase();
var is_opera = userAgent.indexOf('opera') != -1 && opera.version();
var is_moz = (navigator.product == 'Gecko') && userAgent.substr(userAgent.indexOf('firefox') + 8, 3);
var is_ie = (userAgent.indexOf('msie') != -1 && !is_opera) && userAgent.substr(userAgent.indexOf('msie') + 5, 3);
var is_mac = userAgent.indexOf('mac') != -1;
function AC_GetArgs(args, classid, mimeType) {
var ret = new Object();
ret.embedAttrs
= new Object();
ret.params
= new Object();
ret.objAttrs
= new Object();
for (var i = 0; i < args.length; i = i + 2) {
var currArg = args[i].toLowerCase();
switch (currArg) {
case "classid": break;
case "pluginspage": ret.embedAttrs[args[i]] = 'http://www.macromedia.com/go/getflashplayer'; break;
case "src": ret.embedAttrs[args[i]] = args[i + 1]; ret.params["movie"] = args[i + 1]; break;
case "codebase": ret.objAttrs[args[i]] = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0'; break;
case "onafterupdate": case "onbeforeupdate": case "onblur": case "oncellchange": case "onclick": case "ondblclick": case "ondrag": case "ondragend":
case "ondragenter": case "ondragleave": case "ondragover": case "ondrop": case "onfinish": case "onfocus": case "onhelp": case "onmousedown":
case "onmouseup": case "onmouseover": case "onmousemove": case "onmouseout": case "onkeypress": case "onkeydown": case "onkeyup": case "onload":
case "onlosecapture": case "onpropertychange": case "onreadystatechange": case "onrowsdelete": case "onrowenter": case "onrowexit": case "onrowsinserted": case "onstart":
case "onscroll": case "onbeforeeditfocus": case "onactivate": case "onbeforedeactivate": case "ondeactivate": case "type":
case "id": ret.objAttrs[args[i]] = args[i + 1]; break;
case "width": case "height": case "align": case "vspace": case "hspace": case "class": case "title": case "accesskey": case "name":
case "tabindex": ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i + 1]; break;
default: ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i + 1];
}
}
ret.objAttrs[
"classid"] = classid;
if (mimeType) {
ret.embedAttrs[
"type"] = mimeType;
}
return ret;
}
function AC_FL_RunContent() {
var ret = AC_GetArgs(arguments, "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000", "application/x-shockwave-flash");
var str = '';
if (is_ie && !is_opera) {
str
+= '<object ';
for (var i in ret.objAttrs) {
str
+= i + '="' + ret.objAttrs[i] + '" ';
}
str
+= '>';
for (var i in ret.params) {
str
+= '<param name="' + i + '" value="' + ret.params[i] + '" /> ';
}
str
+= '</object>';
}
else {
str
+= '<embed ';
for (var i in ret.embedAttrs) {
str
+= i + '="' + ret.embedAttrs[i] + '" ';
}
str
+= '></embed>';
}
return str;
}



</script>

</head>
<body>
<form id="form1" runat="server">
<table cellspacing="0" cellpadding="0" >
<tbody>
<tr>
<th></th>
<td>
<div class="avatararea">
<p><img id="avatar" onerror="this.onerror=null;this.src='/images/upload/avatars/noavatar_medium.gif';" /></p>
<p><a href="javascript:;" onclick="$('avatarctrl').style.display = ''">Flash头像</a>
</p>
</div>
<div id="avatarctrl" style="display: none">
<script type="text/javascript">
document.write(AC_FL_RunContent(
'width', '540', 'height', '253', 'scale', 'exactfit', 'src', '<% =avatarFlashParam %>', 'id', 'mycamera', 'name', 'mycamera', 'quality', 'high', 'bgcolor', '#ffffff', 'wmode', 'transparent', 'menu', 'false', 'swLiveConnect', 'true', 'allowScriptAccess', 'always'));
</script>
</div>
<script type="text/javascript">
function updateavatar(sender, args) {
$(
'avatar').src = '<%=Localhost %>/images/upload/avatars/<%=uid %>/medium.jpg?random=1' + Math.random();
$(
'avatarctrl').style.display = 'none';
}
updateavatar();
</script>
</td>
</tr>

</tbody>
</table>
</form>
</body>
</html>

  

  .cs代码

代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Avatar
{

public partial class Default : System.Web.UI.Page
{
protected string avatarFlashParam;
protected string EncodeLocalhost;
protected string Localhost;
protected string uid;
protected void Page_Load(object sender, EventArgs e)
{
int port = HttpContext.Current.Request.Url.Port;
string ApplicationPath = HttpContext.Current.Request.ApplicationPath != "/" ? HttpContext.Current.Request.ApplicationPath : string.Empty;
uid
= "1";
Localhost
= string.Format("{0}://{1}{2}{3}",
HttpContext.Current.Request.Url.Scheme,
HttpContext.Current.Request.Url.Host,
(port
== 80 || port == 0) ? "" : ":" + port,
ApplicationPath);
EncodeLocalhost
= HttpUtility.UrlEncode(Localhost);
avatarFlashParam
= string.Format("{0}/images/common/camera.swf?nt=1&inajax=1&appid=1&input={1}&ucapi={2}/Ajax.ashx", Localhost, uid, EncodeLocalhost);
}
}
}

  关键的部分是各个文件的路径,uid是会员的ID,存放会员头像的文件夹名。

 

Ajax.ashx的代码

代码
<%@ WebHandler Language="C#" Class="Ajax" %>

using System;
using System.Web;
using System.IO;

public class Ajax : IHttpHandler {

public void ProcessRequest (HttpContext context) {
string uid = context.Request.QueryString["input"];
if (!string.IsNullOrEmpty(context.Request["Filename"]) && !string.IsNullOrEmpty(context.Request["Upload"]))
{
ResponseText(UploadTempAvatar(uid));
}
if (!string.IsNullOrEmpty(context.Request["avatar1"]) && !string.IsNullOrEmpty(context.Request["avatar2"]) && !string.IsNullOrEmpty(context.Request["avatar3"]))
{

CreateDir(uid);
if (!(SaveAvatar("avatar1", uid) && SaveAvatar("avatar2", uid) && SaveAvatar("avatar3", uid)))
{
File.Delete(GetMapPath(
"images\\upload\\avatars\\" + uid + ".jpg"));
ResponseText(
"<?xml version=\"1.0\" ?><root><face success=\"0\"/></root>");
return;
}
File.Delete(GetMapPath(
"images\\upload\\avatars\\" + uid + ".jpg"));
ResponseText(
"<?xml version=\"1.0\" ?><root><face success=\"1\"/></root>");
return;
}
}

public bool IsReusable {
get {
return false;
}
}

private void CreateDir(string uid)
{
string avatarDir = string.Format("images/upload/avatars/{0}",
uid);
if (!Directory.Exists(GetMapPath(avatarDir)))
Directory.CreateDirectory(GetMapPath(avatarDir));
}

private void ResponseText(string text)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Write(text);
HttpContext.Current.Response.End();
}

private string UploadTempAvatar(string uid)
{
string filename = uid + ".jpg";
string uploadUrl = GetRootUrl("images/") + "upload/avatars";
string uploadDir = GetMapPath("images\\upload\\avatars");
if (!Directory.Exists(uploadDir + "temp\\"))
Directory.CreateDirectory(uploadDir
+ "temp\\");

filename
= "temp/" + filename;
if (HttpContext.Current.Request.Files.Count > 0)
{
HttpContext.Current.Request.Files[
0].SaveAs(uploadDir + filename);
}

return uploadUrl + filename;
}

private byte[] FlashDataDecode(string s)
{
byte[] r = new byte[s.Length / 2];
int l = s.Length;
for (int i = 0; i < l; i = i + 2)
{
int k1 = ((int)s[i]) - 48;
k1
-= k1 > 9 ? 7 : 0;
int k2 = ((int)s[i + 1]) - 48;
k2
-= k2 > 9 ? 7 : 0;
r[i
/ 2] = (byte)(k1 << 4 | k2);
}
return r;
}

private bool SaveAvatar(string avatar, string uid)
{
byte[] b = FlashDataDecode(HttpContext.Current.Request[avatar]);
if (b.Length == 0)
return false;
string size = "";
if (avatar == "avatar1")
size
= "large";
else if (avatar == "avatar2")
size
= "medium";
else
size
= "small";
string avatarFileName = string.Format("images/upload/avatars/{0}/{1}.jpg",
uid, size);
FileStream fs
= new FileStream(GetMapPath(avatarFileName), FileMode.Create);
fs.Write(b,
0, b.Length);
fs.Close();
return true;
}

public static string GetRootUrl(string forumPath)
{
string ApplicationPath = HttpContext.Current.Request.ApplicationPath != "/" ? HttpContext.Current.Request.ApplicationPath : string.Empty;
int port = HttpContext.Current.Request.Url.Port;
return string.Format("{0}://{1}{2}{3}/{4}",
HttpContext.Current.Request.Url.Scheme,
HttpContext.Current.Request.Url.Host,
(port
== 80 || port == 0) ? "" : ":" + port,
ApplicationPath,
forumPath);
}

public static string GetMapPath(string strPath)
{
if (HttpContext.Current != null)
{
return HttpContext.Current.Server.MapPath(strPath);
}
else //非web程序引用
{
strPath
= strPath.Replace("/", "\\");
if (strPath.StartsWith("\\"))
{
strPath
= strPath.Substring(strPath.IndexOf('\\', 1)).TrimStart('\\');
}
return System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, strPath);
}
}
}

  关键的部分是存放头像的路径。这个flash最终会生成 3个大,中,小的头像,如果只需要保存其中一个

if (!string.IsNullOrEmpty(context.Request["avatar1"]) && !string.IsNullOrEmpty(context.Request["avatar2"]) && !string.IsNullOrEmpty(context.Request["avatar3"]))

 

  可以修改这里的代码。

  如果flash 提示 I/0 错误,都是路径的问题。

  总结:flash版的使用相对于silverlight版要简单得多,改动较小,只需修改cs代码,但功能也少(有能力的朋友可以扩展那个 swf的功能)。

   代码下载 https://files.cnblogs.com/geass/Avatar.rar   项目是用 2010,没有的朋友可以单独复制里面的文件。

 

posted @ 2010-10-06 15:37  geass..  阅读(3395)  评论(35编辑  收藏  举报