欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

模拟QQ心情图片上传预览示例

程序员文章站 2024-03-01 14:17:40
出于安全性能的考虑,目前js端不支持获取本地图片进行预览,正好在做一款类似于qq心情的发布框,找了不少jquery插件,没几个能满足需求,因此自己使用swfuplad来实现...
出于安全性能的考虑,目前js端不支持获取本地图片进行预览,正好在做一款类似于qq心情的发布框,找了不少jquery插件,没几个能满足需求,因此自己使用swfuplad来实现这个图片上传预览。

先粘上以下插件,在别的图片上传功能说不定各位能用的上。

1、jquery file upload

demo地址:http://blueimp.github.io/jquery-file-upload/
优点是使用jquery进行图片的异步上传,可控性好,可根据自己的需求任意定制;
缺点是在ie9等一些浏览器中,不支持图片预览,图片选择框中不支持多文件选择(这点是我抛弃它的原因);

2、cfupdate

demo地址:http://www.access2008.cn/update/
优点:使用js+flash实现,兼容所有浏览器,优点界面效果还可以,支持批量上传、支持预览、进度条、删除等功能,作为图片的上传控件非常好用;
缺点:定制型插件,只能修改颜色,样式已经固定死了;

3、swfupload

下载地址:http://code.google.com/p/swfupload/
中文文档帮助地址:http://www.phptogether.com/swfuploadoc/#uploaderror
本文所使用的就是此插件,使用flash+jquery实现,可以更改按钮及各种样式;监听事件也很全。

以下贴出源码及设计思路,主要功能点包括:
1、图片的上传预览(先将图片上传至服务器,然后再返回地址预览,目前抛开html5比较靠谱的预览方式)
2、缩略图的产生(等比例缩放后再截取中间区域作为缩略图,类似qq空间的做法,不过貌似qq空间加入了人脸识别的功能)

以下是此次实现的功能截图:
模拟QQ心情图片上传预览示例 
1、thumbnail.cs

复制代码 代码如下:

public class thumbnial
{
/// <summary>
/// 生成缩略图
/// </summary>
/// <param name="imgsource">原图片</param>
/// <param name="newwidth">缩略图宽度</param>
/// <param name="newheight">缩略图高度</param>
/// <param name="iscut">是否裁剪(以中心点)</param>
/// <returns></returns>
public static image getthumbnail(system.drawing.image imgsource, int newwidth, int newheight, bool iscut)
{
int rwidth = 0; // 等比例缩放后的宽度
int rheight = 0; // 等比例缩放后的高度
int swidth = imgsource.width; // 原图片宽度
int sheight = imgsource.height; // 原图片高度
double wscale = (double)swidth / newwidth; // 宽比例
double hscale = (double)sheight / newheight; // 高比例
double scale = wscale < hscale ? wscale : hscale;
rwidth = (int)math.floor(swidth / scale);
rheight = (int)math.floor(sheight / scale);
bitmap thumbnail = new bitmap(rwidth, rheight);
try
{
// 如果是截取原图,并且原图比例小于所要截取的矩形框,那么保留原图
if (!iscut && scale <= 1)
{
return imgsource;
}

using (graphics tgraphic = graphics.fromimage(thumbnail))
{
tgraphic.interpolationmode = system.drawing.drawing2d.interpolationmode.highqualitybicubic; /* new way */
rectangle rect = new rectangle(0, 0, rwidth, rheight);
rectangle rectsrc = new rectangle(0, 0, swidth, sheight);
tgraphic.drawimage(imgsource, rect, rectsrc, graphicsunit.pixel);
}

if (!iscut)
{
return thumbnail;
}
else
{
int xmove = 0; // 向右偏移(裁剪)
int ymove = 0; // 向下偏移(裁剪)
xmove = (rwidth - newwidth) / 2;
ymove = (rheight - newheight) / 2;
bitmap final_image = new bitmap(newwidth, newheight);
using (graphics fgraphic = graphics.fromimage(final_image))
{
fgraphic.interpolationmode = system.drawing.drawing2d.interpolationmode.highqualitybicubic; /* new way */
rectangle rect1 = new rectangle(0, 0, newwidth, newheight);
rectangle rectsrc1 = new rectangle(xmove, ymove, newwidth, newheight);
fgraphic.drawimage(thumbnail, rect1, rectsrc1, graphicsunit.pixel);
}

thumbnail.dispose();

return final_image;
}
}
catch (exception e)
{
return new bitmap(newwidth, newheight);
}
}
}

2、图片上传处理程序upload.ashx
复制代码 代码如下:

using system;
using system.collections.generic;
using system.linq;
using system.web;
using system.drawing;

namespace mood
{
/// <summary>
/// upload 的摘要说明
/// </summary>
public class upload : ihttphandler
{
image thumbnail;

public void processrequest(httpcontext context)
{
context.response.contenttype = "text/plain";
try
{
string id = system.guid.newguid().tostring();
httppostedfile jpeg_image_upload = context.request.files["filedata"];
image original_image = system.drawing.image.fromstream(jpeg_image_upload.inputstream);
original_image.save(system.web.httpcontext.current.server.mappath("~/files/" + id + ".jpg"));
int target_width = 200;
int target_height = 150;
string path = "files/files200/" + id + ".jpg";
string savethumbnailpath = system.web.httpcontext.current.server.mappath("~/" + path);
thumbnail = thumbnial.getthumbnail(original_image, target_width, target_height, true);
thumbnail.save(savethumbnailpath);
context.response.write(path);
}
catch (exception e)
{
// if any kind of error occurs return a 500 internal server error
context.response.statuscode = 500;
context.response.write("上传过程中出现错误!");
}
finally
{
if (thumbnail != null)
{
thumbnail.dispose();
}
}
}

public bool isreusable
{
get
{
return false;
}
}
}
}

3、前台界面mood.aspx
复制代码 代码如下:

<%@ page language="c#" autoeventwireup="true" codebehind="mood.aspx.cs" inherits="mood.mood" %>

<!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">
<script src="swfupload/swfupload.js" type="text/javascript"></script>
<script src="jquery-1.7.1.js" type="text/javascript"></script>
<link href="style/mood.css" rel="stylesheet" type="text/css" />
<title></title>
<script type="text/javascript">
$().ready(function () {
setswf();
$("#btnreply").click(function () {
$("#divimgs").hide();
});
});

var swfu;
function setswf() {
swfu = new swfupload({
// backend settings
upload_url: "upload.ashx",
// file upload settings
file_size_limit: "20 mb",
file_types: "*.jpg;*.png;*jpeg;*bmp",
file_types_description: "jpg;png;jpeg;bmp",
file_upload_limit: "0", // zero means unlimited
file_queue_error_handler: filequeueerror,
file_dialog_complete_handler: filedialogcomplete,
upload_progress_handler: uploadprogress,
upload_error_handler: uploaderror,
upload_success_handler: uploadsuccess,
upload_complete_handler: uploadcomplete,
// button settings
button_image_url: "/style/image/4-16.png",
button_placeholder_id: "divbtn",
button_width: 26,
button_height: 26,

// flash settings
flash_url: "/swfupload/swfupload.swf",

custom_settings: {
upload_target: "divfileprogresscontainer"
},

// debug settings
debug: false
});
}

// 文件校验
function filequeueerror(file, errorcode, message) {
try {
switch (errorcode) {
case swfupload.queue_error.zero_byte_file:
alert("上传文件有错误!");
break;
case swfupload.queue_error.file_exceeds_size_limit:
alert("上传文件超过限制(20m)!");
break;
case swfupload.queue_error.zero_byte_file:
case swfupload.queue_error.invalid_filetype:
default:
alert("文件出现错误!");
break;
}
} catch (ex) {
this.debug(ex);
}

}

// 文件选择完毕时触发
function filedialogcomplete(numfilesselected, numfilesqueued) {
try {
if (numfilesqueued > 0) {
$("#divimgs").show();
for (var i = 0; i < numfilesqueued; i++) {
$("#ulupload").append('<li id="li' + i + '"><img class="imgload" src="/style/image/loading.gif" alt="" /></li>');
}

this.startupload();
}
} catch (ex) {
this.debug(ex);
}
}

// 滚动条的处理方法 暂时没写
function uploadprogress(file, bytesloaded) {
}

// 每个文件上传成功后的处理
function uploadsuccess(file, serverdata) {
try {
var index = file.id.substr(file.id.lastindexof('_') + 1);
$("#li" + index).html("");
$("#li" + index).html('<img src="' + serverdata + '" alt=""/>');
index++;

} catch (ex) {
this.debug(ex);
}
}

// 上传完成后,触发下一个文件的上传
function uploadcomplete(file) {
try {
if (this.getstats().files_queued > 0) {
this.startupload();
}
} catch (ex) {
this.debug(ex);
}
}

// 单个文件上传错误时处理
function uploaderror(file, errorcode, message) {
var imagename = "imgerror.png";
try {
var index = file.id.substr(file.id.lastindexof('_') + 1);
$("#li" + index).html("");
$("#li" + index).html('<img src="/style/image/imgerror.png" alt=""/>');
index++;
} catch (ex3) {
this.debug(ex3);
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div style="width: 600px;">
<div class="divtxt">
文本框
</div>
<div style="height: 30px; line-height: 30px;">
<div id="divbtn" style="float: left; width: 26px; height: 26px;">
</div>
<div style="float: right;">
<input id="btnreply" type="button" value="发表" />
</div>
</div>
<div id="divimgs" style="border: 1px solid #cdcdcd; display: none;">
<div>
上传图片</div>
<ul id="ulupload" class="ulupload">
</ul>
</div>
</div>
</form>
</body>
</html>

使用vs2010开发,以下为项目源码地址