• PictureWebHandler


    using System;
    using System.Configuration;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Globalization;
    using System.IO;
    using System.Text.RegularExpressions;
    using System.Web;
    using EW.EWorkpal.Core.Common.MongoProvider.MongoGridFSRepository.Models;
    using EW.EWorkpal.Core.System;
    using EW.EWorkpal.Services.FileManagerService.ImageProvider;
    
    namespace EW.EWorkpal.Modules.Picture
    {
        public class PictureWebHandler : ServiceBase, IHttpHandler
        {
            public void ProcessRequest(HttpContext context)
            {
                HttpResponse response = context.Response;
                HttpRequest request = context.Request;
                #region 客户端缓存
                int clientCacheTime;   //客户端缓存时间(秒)
                string clientCacheSecond = GetAppSetting("ClientCacheSecond", true);
                if (!int.TryParse(clientCacheSecond, out clientCacheTime))
                    clientCacheTime = 3600;
                string clearHeadImage = request.Headers["Clear-HeadImage"];
                if (!string.IsNullOrEmpty(clearHeadImage))
                {
                    ClearClientCaching(context.Response);
                    return;
                }
                string headerModified = request.Headers["If-Modified-Since"];
                if (headerModified != null)
                {
                    long nowTicks = DateTime.Now.Ticks;
                    long modifiedTick = DateTime.Parse(request.Headers["If-Modified-Since"]).Ticks;
                    long ticks = nowTicks - modifiedTick;
                    if (TimeSpan.FromTicks(ticks).Seconds < clientCacheTime)
                    {
                        response.StatusCode = 304;
                        // 这种方式会产生“此操作要求使用 IIS 集成管线模式。 ”的异常  
                        //Response.Headers.Add("Content-Encoding", "gzip");  
                        // Response.Headers.Add 和 Response.AddHeader 但是在MSDN中明确写出,这些都是为了兼容ASP,在.NET 3.5要求使用下面这种方式。  
                        //这种方式不会出现异常  
                        response.AppendHeader("Content-Encoding", "gzip");
                        response.StatusDescription = "Not Madified";
                        response.End();
                        return;
                    }
                }
                #endregion
                string regex = GetAppSetting("UrlRegex");
                string sourceRegex = GetAppSetting("SourceUrlRegex");
                string headRegex = GetAppSetting("HeadImageUrlRegex");
                string comLogoRegex = GetAppSetting("ComLogoUrlRegex");
                string url = request.Url.AbsoluteUri;
                int regexIndex;
                if (Regex.IsMatch(url, headRegex, RegexOptions.IgnoreCase))
                    regexIndex = 3;
                else if (Regex.IsMatch(url, comLogoRegex, RegexOptions.IgnoreCase))
                    regexIndex = 4;
                else if (Regex.IsMatch(url, regex, RegexOptions.IgnoreCase))
                    regexIndex = 1;
                else if (Regex.IsMatch(url, sourceRegex, RegexOptions.IgnoreCase))
                    regexIndex = 2;
                else
                    regexIndex = 0;
                if (regexIndex == 0)
                {
                    Error404(response);
                    return;
                }
                #region 用户头像
                if (regexIndex == 3)
                {
                    var regResult = Regex.Match(url, @"d+/d+").Value;
                    var str = regResult.Split('/');
                    if (str.Length < 2)
                    {
                        Error404(response);
                        return;
                    }
                    int id, size;
                    if (!int.TryParse(str[0], out id))
                    {
                        Error404(response);
                        return;
                    }
                    if (!int.TryParse(str[1], out size))
                    {
                        Error404(response);
                        return;
                    }
                    if (size == 0)
                    {
                        size = 50;
                    }
                    else if (size == 1)
                    {
                        size = 80;
                    }
                    else
                    {
                        size = 150;
                    }
                    var srcPicBytes = GetService<IImageService>().GetHeadImage(id);
                    if (srcPicBytes != null)
                    {
                        Stream stream = GetHighHeadImage(srcPicBytes, size);
                        long dataToRead = stream.Length;
                        byte[] bytes = ((MemoryStream)stream).GetBuffer();
                        response.Buffer = true;
                        response.ContentType = "image/jpeg";
                        while (dataToRead > 0)
                        {
                            if (response.IsClientConnected)
                            {
                                int length = bytes.Length;
                                byte[] buffer = bytes;
                                response.OutputStream.Write(buffer, 0, length);
                                response.Flush();
                                dataToRead = dataToRead - length;
                            }
                            else
                            {
                                dataToRead = -1;
                            }
                        }
                        SetClientCaching(response, DateTime.Now, clientCacheTime);
                    }
                    else
                    {
                        //if (requesthost != picturehost)//盗链,返回提示图片  
                        ////{
                        ////    context.Response.WriteFile("/Img/linknotice/ImageForbiden.jpg");
                        ////}
                        context.Response.ClearContent();
                        context.Response.WriteFile("/img/headimg/noavatar_" + size + "_" + size + ".jpg");
                        context.Response.ContentType = "image/jpeg";
                        context.Response.End();
                        return;
    
                    }
    //                context.Response.ClearContent();
    //                context.Response.ContentType = "image/jpeg";
                    context.Response.End();
                    return;
                }
    
                #endregion
    
                #region 企业Logo
                if (regexIndex == 4)
                {
                    var regResult = Regex.Match(url, @"ent/d+").Value;
                    var str = regResult.Split('/');
                    if (str.Length < 2)
                    {
                        Error404(response);
                        return;
                    }
                    int size;
                    if (!int.TryParse(str[1], out size))
                    {
                        Error404(response);
                        return;
                    }
                    if (size == 0)
                    {
                        size = 50;
                    }
                    else if (size == 1)
                    {
                        size = 100;
                    }
                    else
                    {
                        size = 150;
                    } 
                    string fileName = regexIndex == 1 ? Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[1].Value : Regex.Match(url, sourceRegex, RegexOptions.IgnoreCase).Groups[1].Value;
                    MongoFileInfo options;
                    var srcPicBytes = GetService<IImageService>().Get(fileName, out options);
                    if (srcPicBytes != null)
                    {
                        Stream stream = GetHighHeadImage(srcPicBytes, size);
                        long dataToRead = stream.Length;
                        byte[] bytes = ((MemoryStream)stream).GetBuffer();
                        response.Buffer = true;
                        response.ContentType = "image/jpeg";
                        while (dataToRead > 0)
                        {
                            if (response.IsClientConnected)
                            {
                                int length = bytes.Length;
                                byte[] buffer = bytes;
                                response.OutputStream.Write(buffer, 0, length);
                                response.Flush();
                                dataToRead = dataToRead - length;
                            }
                            else
                            {
                                dataToRead = -1;
                            }
                        }
                        SetClientCaching(response, DateTime.Now, clientCacheTime);
                    }
                    else
                    {
                        context.Response.ClearContent();
                        context.Response.WriteFile(string.Format("/img/comlogo/{0}x{0}.jpg",size));
                        context.Response.ContentType = "image/jpeg";
                        context.Response.End();
                        return;
    
                    }
    //                context.Response.ClearContent();
    //                context.Response.ContentType = "image/jpeg";
                    context.Response.End();
                    return;
                } 
                #endregion
    
                #region 读取原图
    
                if (regexIndex == 1 || regexIndex == 2)
                {
                    string fileName = regexIndex == 1 ? Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[1].Value : Regex.Match(url, sourceRegex, RegexOptions.IgnoreCase).Groups[1].Value;
                    MongoFileInfo options;
                    var srcPicBytes = GetService<IImageService>().Get(fileName, out options);
                    if (srcPicBytes == null || srcPicBytes.Length <= 0)
                    {
                        Error404(response);
                        return;
                    }
                    var srcPicStream = new MemoryStream(srcPicBytes);
                    Image srcImage = Image.FromStream(srcPicStream);
                    Image destImage = null;
                    if (regexIndex == 1)
                    {
                        int destWidth = int.Parse(Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[2].Value);
                        int destHeight = int.Parse(Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[3].Value);
                        string zoomType = Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[4].Value;
                        bool zoomCut = zoomType.ToUpper() == "-C";
                        bool zoomFit = zoomType.ToUpper() == "-F";
                        //缩略
                        destImage = ZoomPic.Zoom(srcImage,
                                                 new ZoomParam
                                                 {
                                                     Width = destWidth,
                                                     Height = destHeight,
                                                     Type =
                                                         zoomCut
                                                             ? EnumZoomType.Cut
                                                             : zoomFit ? EnumZoomType.Fit : EnumZoomType.Cut
                                                 });
                    }
                    else
                    {
                        //返回原图
                        destImage = srcImage;
                    }
                    #region 输出
                    Stream stream = new MemoryStream();
                    try
                    {
                        if (destImage != null) destImage.Save(stream, ImageFormat.Jpeg);
                        long dataToRead = stream.Length;
                        byte[] bytes = ((MemoryStream)stream).GetBuffer();
                        SetClientCaching(response, DateTime.Now, clientCacheTime);
                        response.Buffer = true;
                        response.ContentType = "image/jpeg";
                        while (dataToRead > 0)
                        {
                            if (response.IsClientConnected)
                            {
                                int length = bytes.Length;
                                byte[] buffer = bytes;
                                response.OutputStream.Write(buffer, 0, length);
                                response.Flush();
                                dataToRead = dataToRead - length;
                            }
                            else
                            {
                                dataToRead = -1;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        ClearClientCaching(response);
                        throw new Exception(e.Message);
                    }
                    finally
                    {
                        srcImage.Dispose();
                        srcPicStream.Dispose();
                        if (destImage != null) destImage.Dispose();
                        stream.Dispose();
                    }
                    #endregion
                }
    
                #endregion
    
            }
    
            #region private methods
    
            private static string GetAppSetting(string key, bool allowNull = false)
            {
                if (ConfigurationManager.AppSettings[key] == null)
                {
                    if (allowNull)
                        return "";
                    throw new ConfigurationErrorsException(string.Format("找不到appSettings配置,配置项{0}", key));
                }
                return ConfigurationManager.AppSettings[key];
            }
    
            private void SetClientCaching(HttpResponse response, DateTime lastModified, int clientCacheTime)
            {
                response.ContentType = "image/jpeg";
                //将ETag Http标头设置为制定字符串  
                response.Cache.SetETag(lastModified.Ticks.ToString(CultureInfo.InvariantCulture));
                //将Last_Modified Http标头设置为提供的System.DateTime值  
                response.Cache.SetLastModified(lastModified);
                //将Cache-Control 标头设置为System.Web.HttpCacheability值之一  
                response.Cache.SetCacheability(HttpCacheability.Public);
                //基于制定的时间跨度设置Cache-Control: max-age HTTP标头  
                response.Cache.SetMaxAge(new TimeSpan(0, 0, 0, clientCacheTime));
                //将缓存过期从绝对时间设置为可调时间  
                response.Cache.SetSlidingExpiration(true);
            }
    
            private void ClearClientCaching(HttpResponse response)
            {
                response.Cache.SetExpires(DateTime.Now);
            }
    
            private MemoryStream GetHeadImage(Byte[] file, int size)
            {
                size = size > 150 ? 150 : size;
                MemoryStream stream = new MemoryStream(file);
                Bitmap bmp = new Bitmap(Image.FromStream(stream));
                Image image = bmp.GetThumbnailImage(size, size, null, IntPtr.Zero);
                MemoryStream ms = new MemoryStream();
                image.Save(ms, ImageFormat.Jpeg);
                return ms;
            }
    
            private MemoryStream GetHighHeadImage(Byte[] file, int size)
            {
                MemoryStream ms = new MemoryStream();
                Image originalImage = Image.FromStream(new MemoryStream(file));
                //新建一个bmp图片
                Image bitmap = new Bitmap(size, size);
                //新建一个画板
                Graphics g = Graphics.FromImage(bitmap);
                //设置高质量插值法
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                //设置高质量,低速度呈现平滑程度
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //清空画布并以透明背景色填充
                g.Clear(Color.Transparent);
                //在指定位置并且按指定大小绘制原图片的指定部分
                g.DrawImage(originalImage, new Rectangle(0, 0, size, size), new Rectangle(0, 0, originalImage.Width, originalImage.Height), GraphicsUnit.Pixel);
                try
                {
                    //以jpg格式保存缩略图
                    bitmap.Save(ms, ImageFormat.Png);
                }
                catch (Exception e)
                {
                    throw e;
                }
                finally
                {
                    originalImage.Dispose();
                    bitmap.Dispose();
                    g.Dispose();
                }
                return ms;
            }
    
            #endregion
    
            /// <summary>
            /// 返回404
            /// </summary>
            private static void Error404(HttpResponse response)
            {
                response.StatusCode = 404;
                response.Flush();
                response.End();
            }
    
            public bool IsReusable { get { return false; } }
        }
    }
  • 相关阅读:
    js 所有事件列表
    ironpython
    BAT批处理基本命令总结
    cmd命令行大全 dos命令 cmd命令整理
    Oracle向MySQL迁移
    python html转pdf
    python3 图片验证码
    Python 发送邮件
    如何卸载虚拟机
    django开发网站 让局域网中的电脑访问你的主机
  • 原文地址:https://www.cnblogs.com/kingCpp/p/4649144.html
Copyright © 2020-2023  润新知