⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monsterhandler.cs

📁 个人博客系统
💻 CS
字号:
#region Using

using System;
using System.Web;
using System.Net;
using System.Globalization;
using System.Web.Hosting;
using System.Drawing;
using System.IO;

#endregion

namespace BlogEngine.Core.Web.HttpHandlers
{
  /// <summary>
  /// Creates images of monsters based on a md5 hash. It is used
  /// for displaying avatar icons in the comments.
  /// <remarks>
  /// This handler is based on the MonsterID HttpHandler by Alexander Schuc
  /// http://blog.furred.net/page/MonsterID-Demo.aspx
  /// </remarks>
  /// </summary>
  public class MonsterHandler : IHttpHandler
  {

    #region Private fields

    private const string CACHE_PATH = "~/App_Data/monstercache/{0}";
    private const string PARTS_PATH = "~/pics/monsterparts";

    private static readonly string[] parts = new string[] { "legs", "hair", "arms", "body", "eyes", "mouth" };
    private static readonly int[] partcount = new int[] { 5, 5, 5, 15, 15, 10 };

    #endregion

    #region IHttpHandler Members

    /// <summary>
    /// Enables processing of HTTP Web requests by a custom HttpHandler that 
    /// implements the <see cref="T:System.Web.IHttpHandler"></see> interface.
    /// </summary>
    /// <param name="context">An <see cref="T:System.Web.HttpContext"></see> object that provides 
    /// references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
    public void ProcessRequest(HttpContext context)
    {
      if (String.IsNullOrEmpty(context.Request.QueryString["seed"]) || String.IsNullOrEmpty(context.Request.QueryString["size"]))
        return;

      string md5 = context.Request.QueryString["seed"];
      int seed = int.Parse(md5.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
      int size = int.Parse(context.Request.QueryString["size"], CultureInfo.InvariantCulture);

      string filename = GetMonsterFilename(seed, size); //GetMonster(seed, size);

      if (!File.Exists(filename))
        CreateMonster(seed, size, filename);

      SetHttpHeaders(context, md5);
      context.Response.WriteFile(filename);
    }

    /// <summary>
    /// Gets a value indicating whether another request can use the <see cref="T:System.Web.IHttpHandler"></see> instance.
    /// </summary>
    /// <value></value>
    /// <returns>true if the <see cref="T:System.Web.IHttpHandler"></see> instance is reusable; otherwise, false.</returns>
    public bool IsReusable
    {
      get { return true; }
    }

    #endregion

    /// <summary>
    /// This will make the browser and server keep the output
    /// in its cache and thereby improve performance.
    /// </summary>
    private static void SetHttpHeaders(HttpContext context, string md5)
    {
      string etag = "\"" + md5.GetHashCode() + "\"";
      string incomingEtag = context.Request.Headers["If-None-Match"];

      context.Response.ContentType = "image/png";
      context.Response.Cache.SetCacheability(HttpCacheability.Public);
      context.Response.Cache.SetExpires(DateTime.Now.AddYears(1));
      context.Response.Cache.SetETag(md5);

      if (String.Compare(incomingEtag, etag) == 0)
      {
        context.Response.StatusCode = (int)HttpStatusCode.NotModified;
        context.Response.End();
      }
    }

    /// <summary>
    /// Gets the filename of the monster based on the seed and size.
    /// </summary>
    private static string GetMonsterFilename(int seed, int size)
    {
      CultureInfo info = CultureInfo.InvariantCulture;
      return Path.Combine(HostingEnvironment.MapPath(string.Format(info, CACHE_PATH, size)), string.Format(info, "{0}.png", seed));
    }

    /// <summary>
    /// Creates the monster image and saves it to the cache on disk.
    /// </summary>
    private static void CreateMonster(int seed, int size, string filename)
    {
      string sourcedir = HostingEnvironment.MapPath(PARTS_PATH);
      Random rnd = new Random(seed);
      int[] currentParts = new int[parts.Length];

      for (int i = 0; i < currentParts.Length; i++)
      {
        currentParts[i] = rnd.Next(1, partcount[i]);
      }

      using (Bitmap bmp = new Bitmap(size, size))
      {
        Bitmap overlay;
        using (Graphics gfx = Graphics.FromImage(bmp))
        {
          gfx.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
          gfx.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

          for (int i = 0; i < currentParts.Length; i++)
          {
            using (overlay = new Bitmap(Path.Combine(sourcedir, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.png", parts[i], currentParts[i]))))
            {
              Rectangle rect = new Rectangle(new Point(0), overlay.Size);
              gfx.DrawImage(overlay, new Rectangle(new Point(0), bmp.Size), rect, GraphicsUnit.Pixel);
            }
          }
        }

        string path = Path.GetDirectoryName(filename);
        if (!Directory.Exists(path))
          Directory.CreateDirectory(path);

        bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
      }
    }

  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -