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 = ;
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 = ;
// 这种方式会产生“此操作要求使用 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 = ;
else if (Regex.IsMatch(url, comLogoRegex, RegexOptions.IgnoreCase))
regexIndex = ;
else if (Regex.IsMatch(url, regex, RegexOptions.IgnoreCase))
regexIndex = ;
else if (Regex.IsMatch(url, sourceRegex, RegexOptions.IgnoreCase))
regexIndex = ;
else
regexIndex = ;
if (regexIndex == )
{
Error404(response);
return;
}
#region 用户头像
if (regexIndex == )
{
var regResult = Regex.Match(url, @"\d+/\d+").Value;
var str = regResult.Split('/');
if (str.Length < )
{
Error404(response);
return;
}
int id, size;
if (!int.TryParse(str[], out id))
{
Error404(response);
return;
}
if (!int.TryParse(str[], out size))
{
Error404(response);
return;
}
if (size == )
{
size = ;
}
else if (size == )
{
size = ;
}
else
{
size = ;
}
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 > )
{
if (response.IsClientConnected)
{
int length = bytes.Length;
byte[] buffer = bytes;
response.OutputStream.Write(buffer, , length);
response.Flush();
dataToRead = dataToRead - length;
}
else
{
dataToRead = -;
}
}
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 == )
{
var regResult = Regex.Match(url, @"ent/\d+").Value;
var str = regResult.Split('/');
if (str.Length < )
{
Error404(response);
return;
}
int size;
if (!int.TryParse(str[], out size))
{
Error404(response);
return;
}
if (size == )
{
size = ;
}
else if (size == )
{
size = ;
}
else
{
size = ;
}
string fileName = regexIndex == ? Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[].Value : Regex.Match(url, sourceRegex, RegexOptions.IgnoreCase).Groups[].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 > )
{
if (response.IsClientConnected)
{
int length = bytes.Length;
byte[] buffer = bytes;
response.OutputStream.Write(buffer, , length);
response.Flush();
dataToRead = dataToRead - length;
}
else
{
dataToRead = -;
}
}
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 == || regexIndex == )
{
string fileName = regexIndex == ? Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[].Value : Regex.Match(url, sourceRegex, RegexOptions.IgnoreCase).Groups[].Value;
MongoFileInfo options;
var srcPicBytes = GetService<IImageService>().Get(fileName, out options);
if (srcPicBytes == null || srcPicBytes.Length <= )
{
Error404(response);
return;
}
var srcPicStream = new MemoryStream(srcPicBytes);
Image srcImage = Image.FromStream(srcPicStream);
Image destImage = null;
if (regexIndex == )
{
int destWidth = int.Parse(Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[].Value);
int destHeight = int.Parse(Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[].Value);
string zoomType = Regex.Match(url, regex, RegexOptions.IgnoreCase).Groups[].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 > )
{
if (response.IsClientConnected)
{
int length = bytes.Length;
byte[] buffer = bytes;
response.OutputStream.Write(buffer, , length);
response.Flush();
dataToRead = dataToRead - length;
}
else
{
dataToRead = -;
}
}
}
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(, , , clientCacheTime));
//将缓存过期从绝对时间设置为可调时间
response.Cache.SetSlidingExpiration(true);
} private void ClearClientCaching(HttpResponse response)
{
response.Cache.SetExpires(DateTime.Now);
} private MemoryStream GetHeadImage(Byte[] file, int size)
{
size = size > ? : 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(, , size, size), new Rectangle(, , 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 = ;
response.Flush();
response.End();
} public bool IsReusable { get { return false; } }
}
}

PictureWebHandler的更多相关文章

随机推荐

  1. 9月java货车版速记

    运算符的优先级java自带的方法正则表达式数组和二维数组:数组遍历,填充数组,数组排序,复制数组,数组查询数组算法:冒泡,选择,反转,快速类和对象:封装,继承,多态,this关键字,抽象类和接口重写和 ...

  2. EAPOL 协议

    EAPOL 协议 一.基本概念 EAPOL 的全称为 Extensible Authentication Protocol Over LAN,即 EAP Over Lan,也即基于局域网的扩展认证协议 ...

  3. 两个EXCEL文件对比去重

    两个EXCEL文件,A里面有10000条记录,B里面有4000条记录,A的记录包含了B里面所有的记录现在如何能把A里面没有包含B的6000条记录筛选出来? 那你要把两同时打开,比如book1 book ...

  4. spring.hibernate设置参数的位置问题

    1.spring的注解设置在set方法上 2.hibernate的注解设置在get方法上

  5. ctrl + d 在phpstorm 和 eclipse 中的不同含义

    Ctrl + d 在phpstrom是复制一行,非常的方便,但是eclipse中却是删除一行,非常的特别.感觉上,phpstorm更注重鼠标,但eclipse貌似更多鼠标和键盘的操作, 默认情况下[p ...

  6. 安卓App热补丁动态修复技术介绍

    版权声明:本文由johncz原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/169 来源:腾云阁 https://www.q ...

  7. js更改input标签的读写属性

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 【bzoj1027】合金

    [bzoj1027]合金 分析 数形结合+计算几何+Floyd最小环. http://blog.csdn.net/popoqqq/article/details/40539273 虽然这样占大家的很不 ...

  9. Laravel 分页详解

    Laravel分页很简单,但功能又很强大噢! 首先在控制器的方法中使用paginate(页面显示条数)方法,传入页面显示的条数 然后在模板页面使用方法render()来生成html元素 appends ...

  10. 3.5 EF Code First总结

    1. 主键约定 属性名为“ID”(不区分大小写)或类名的后面跟有“ID”. 2. 关系约定 模型之间的关系,EF根据针对类型定义的导航属性来推断关系. 3. 连接字符串约定 (1)默认配置 如果连接字 ...