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

  出于安全性能的考虑,目前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开发,以下为项目源码地址