Created
February 16, 2021 17:34
-
-
Save BillKeenan/49c890ae6ea64ff77d53cec109d002a5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Configuration; | |
using System.Diagnostics; | |
using System.Drawing; | |
using System.Drawing.Imaging; | |
using System.Globalization; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Security.Policy; | |
using System.ServiceModel.Web; | |
using System.Text; | |
using System.Web; | |
using System.Web.Caching; | |
using Core.Model; | |
using Core.Model.impl; | |
using Core.Repositories.interfaces; | |
using Core.Utility; | |
using IOC; | |
using ServiceInterfaces; | |
using StructureMap; | |
namespace PlayService | |
{ | |
/// <summary> | |
/// Summary description for ImageHandler | |
/// </summary> | |
public class ImageHandler : IHttpHandler | |
{ | |
private IDatabaseHandler _databaseHandler; | |
private ILoggerService _loggerService; | |
private readonly IDropDeckCacheProvider _dropDeckCacheProvider; | |
public ImageHandler( ) | |
{ | |
Bootstrapper.Bootstrap(); | |
_databaseHandler = ObjectFactory.GetInstance<IDatabaseHandler>(); | |
_loggerService = ObjectFactory.GetInstance<ILoggerService>() ; | |
_dropDeckCacheProvider = ObjectFactory.GetInstance<IDropDeckCacheProvider>(); | |
} | |
public void ProcessRequest(HttpContext context) | |
{ | |
var url = context.Request.RawUrl; | |
var fi = (FileInfo) HttpRuntime.Cache.Get(url); | |
if (fi == null || !fi.Exists) | |
{ | |
var parmas = url.Split(Char.Parse("/"), Char.Parse("?")); | |
int width = 0; | |
int height = 0; | |
if (parmas.Length > 3) | |
{ | |
var queryParams = QueryHelper.SplitParams(parmas[3]); | |
//get width) | |
if (queryParams.ContainsKey("width")) | |
{ | |
int.TryParse(queryParams["width"], out width); | |
} | |
//get width) | |
if (queryParams.ContainsKey("height")) | |
{ | |
int.TryParse(queryParams["height"], out height); | |
} | |
} | |
fi = HandleLocalImage(Convert.ToInt32(parmas[2]), context, width, height); | |
} | |
if (fi != null ) | |
{ | |
HttpRuntime.Cache.Add(url, fi, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, | |
CacheItemPriority.Normal, null); | |
ReturnImage(fi, context); | |
} | |
else | |
{ | |
context.Response.StatusCode = 404; | |
return; | |
} | |
} | |
private FileInfo HandleLocalImage(int id, HttpContext context,int width,int height) | |
{ | |
var key = String.Format("Image{0}Cache", id); | |
var resizedkey = String.Format("Image{0}Cache_w:{1}_h:{2}", id,width,height); | |
FileInfo fi = null; | |
var sizedFile = (string)HttpRuntime.Cache.Get(resizedkey); | |
if (!String.IsNullOrEmpty(sizedFile) && File.Exists(sizedFile) ) | |
{ | |
fi = new FileInfo(sizedFile); | |
} | |
else | |
{ | |
var origFile = (string) HttpRuntime.Cache.Get(key); | |
//get the original filepath | |
if (String.IsNullOrEmpty(origFile)) | |
{ | |
var filePath = GetImage(id); | |
if (!String.IsNullOrEmpty(filePath)) | |
{ | |
origFile = String.Format("{0}{1}", ConfigurationManager.AppSettings["ImagePath"], filePath); | |
HttpRuntime.Cache.Add(key, origFile, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, | |
CacheItemPriority.Normal, null); | |
} | |
} | |
//does the file exist? | |
if (!String.IsNullOrEmpty(origFile)) | |
{ | |
if (!File.Exists(origFile)) | |
{ | |
_loggerService.Fatal("404:" + origFile); | |
context.Response.StatusCode = 404; | |
return null; | |
} | |
} | |
fi = new FileInfo(origFile); | |
//build the sized url | |
if (width > 0 || height > 0) | |
{ | |
var sized = String.Format(@"{0}\{1}", fi.DirectoryName, getFileName(fi.Name, width, height)); | |
//does it exist? | |
if (!File.Exists(sized) ) | |
{ | |
//create it | |
fi = ResizeImage(width, height, fi); | |
} | |
else | |
{ | |
fi = new FileInfo(sized); | |
} | |
HttpRuntime.Cache.Add(resizedkey, sized, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, | |
CacheItemPriority.Normal, null); | |
} | |
} | |
return fi; | |
} | |
public void ReturnImage(FileInfo file, HttpContext context) | |
{ | |
var etag = Md5Util.GetMd5Hash(file.LastWriteTime.Ticks + file.FullName); | |
context.Cache[file.FullName] = etag; | |
switch (file.Extension.ToLower()) | |
{ | |
case ".jpg": | |
context.Response.ContentType = "image/jpeg"; | |
break; | |
case ".png": | |
context.Response.ContentType = "image/png"; | |
break; | |
case ".gif": | |
context.Response.ContentType = "image/gif"; | |
break; | |
default: | |
throw new ArgumentException("Unknown filetype:" + file.Extension); | |
} | |
context.Response.Cache.SetCacheability(HttpCacheability.Public); | |
context.Response.Cache.SetExpires(DateTime.Now.AddDays(1)); | |
context.Response.Cache.SetMaxAge(new TimeSpan(24, 0, 0)); | |
context.Response.Cache.SetETag(etag); | |
context.Response.WriteFile(file.FullName); | |
} | |
private void ProxyFaceBookAvatar(string[] parmas, HttpContext context) | |
{ | |
if (parmas.Count()<3) | |
{ | |
context.Response.StatusCode = 500; | |
return; | |
} | |
var id = int.Parse(parmas[3]); | |
var fileName = String.Format("{0}{1}.jpg", ConfigurationManager.AppSettings["FaceBookAvatar"], id); | |
var url = String.Format("http://graph.facebook.com/{0}/picture",id); | |
var fi = new FileInfo(fileName); | |
if (!fi.Exists) | |
{ | |
fi = ImageDownloader.DownloadAndSave(url, fileName); | |
} | |
ReturnImage(fi,context); | |
} | |
public string GetImage(int id) | |
{ | |
var image = _databaseHandler.Session.Get<Media>(id); | |
if (image== null || string.IsNullOrEmpty(image.Path)) | |
{ | |
_loggerService.Fatal("could not find media id:" + id); | |
return null; | |
} | |
_loggerService.Info(String.Format("Returning image:{0}",image.Path)); | |
return image.Path; | |
} | |
public bool IsReusable | |
{ | |
get | |
{ | |
return false; | |
} | |
} | |
private static string getFileName(string name,int width,int height) | |
{ | |
var sb = new StringBuilder(); | |
sb.Append(width); | |
sb.Append("_"); | |
sb.Append(height); | |
sb.Append("_"); | |
sb.Append(name); | |
return sb.ToString(); | |
} | |
public static FileInfo ResizeImage(int width, int height,FileInfo fi) | |
{ | |
if (width == 0 && height == 0) | |
{ | |
return fi; | |
} | |
var newFileName = String.Format(@"{0}\{1}", fi.Directory, getFileName(fi.Name, width, height)); | |
if (File.Exists(newFileName)) | |
{ | |
var newFi = new FileInfo(newFileName); | |
return newFi; | |
} | |
FileInfo finalFI; | |
//load up the image | |
using (var image = Image.FromFile(fi.FullName)) | |
{ | |
var scale = (double)width / (double)image.Width; | |
var jgpEncoder = GetEncoder(ImageFormat.Jpeg); | |
var myEncoder = System.Drawing.Imaging.Encoder.Quality; | |
var myEncoderParameters = new EncoderParameters(1); | |
var myEncoderParameter = new EncoderParameter(myEncoder, 50L); | |
myEncoderParameters.Param[0] = myEncoderParameter; | |
using (var fullsizeImage = Image.FromFile(fi.FullName)) | |
{ | |
//get newSize | |
var newSize = NewSize(fullsizeImage.Size, new Size(width, height)); | |
// Prevent using images internal thumbnail | |
fullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); | |
fullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); | |
using (var newImage = fullsizeImage.GetThumbnailImage(newSize.Width, newSize.Height, null, IntPtr.Zero)) | |
{ | |
// Clear handle to original file so that we can overwrite it if necessary | |
// Save resized picture | |
newImage.Save(newFileName, jgpEncoder, myEncoderParameters); | |
newImage.Dispose(); | |
finalFI = new FileInfo(newFileName); | |
} | |
fullsizeImage.Dispose(); | |
} | |
} | |
return finalFI; | |
} | |
private static float GetRatio(Size size) | |
{ | |
return (float)size.Width/size.Height; | |
} | |
public static Size NewSize(Size origSize,Size newSize) | |
{ | |
var finalSize = new Size(); | |
var origRatio = GetRatio(origSize); | |
var newRatio = GetRatio(newSize); | |
if (origRatio>newRatio) | |
{ | |
//width is our base | |
finalSize.Width = newSize.Width; | |
finalSize.Height = (int)(finalSize.Width / origRatio); | |
}else if (origRatio < newRatio) | |
{ | |
//height is our base | |
finalSize.Height = newSize.Height; | |
finalSize.Width = (int)(finalSize.Height * origRatio); | |
}else | |
{ | |
//mathching! | |
finalSize = newSize; | |
} | |
return finalSize; | |
} | |
private static ImageCodecInfo GetEncoder(ImageFormat format) | |
{ | |
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders(); | |
foreach (ImageCodecInfo codec in codecs) | |
{ | |
if (codec.FormatID == format.Guid) | |
{ | |
return codec; | |
} | |
} | |
return null; | |
} | |
} | |
public class QueryHelper | |
{ | |
public static string BuildQueryParam(Uri theUri, string key, string value) | |
{ | |
var qVal = theUri.Query; | |
if (theUri.Query.Length > 0) | |
{ | |
qVal = theUri.Query.Substring(1, theUri.Query.Length - 1); | |
} | |
var vals = QueryHelper.SplitParams(qVal); | |
var val2 = new Dictionary<string, string>(); | |
foreach (var val in vals) | |
{ | |
if (val.Key == key) | |
{ | |
continue; | |
} | |
//handle clearing 'all' | |
if (val.Key.ToLower() == "all" && key.ToLower() != "all") | |
{ | |
continue; | |
} | |
val2.Add(val.Key, val.Value); | |
} | |
if (!String.IsNullOrEmpty(value)) | |
{ | |
val2[key] = value; | |
} | |
var sb = new StringBuilder(); | |
sb.Append("?"); | |
foreach (var obKey in val2.Keys) | |
{ | |
if (sb.Length > 1) | |
{ | |
sb.Append("&"); | |
} | |
var queryVal = HttpUtility.UrlDecode(val2[obKey]); | |
sb.Append(String.Format("{0}={1}", obKey, HttpUtility.UrlEncode(queryVal))); | |
} | |
return sb.ToString(); | |
} | |
public static Dictionary<string, string> SplitParams(string uri) | |
{ | |
var parts = uri.Split(Char.Parse("&")); | |
var val = new Dictionary<string, string>(); | |
foreach (var part in parts) | |
{ | |
var item = part.Split(Char.Parse("=")); | |
if (item.Length == 2) | |
{ | |
val[item[0]] = item[1]; | |
} | |
} | |
return val; | |
} | |
} | |
public class ImageDownloader | |
{ | |
public static FileInfo DownloadAndSave(string imageUrl, string destinationFile) | |
{ | |
try | |
{ | |
var client = new WebClient(); | |
using (var stream = client.OpenRead(imageUrl)) | |
{ | |
if (stream != null) | |
{ | |
using (var bitmap = new Bitmap(stream)) | |
{ | |
stream.Flush(); | |
stream.Close(); | |
stream.Dispose(); | |
bitmap.Save(destinationFile); | |
bitmap.Dispose(); | |
} | |
var fi = new FileInfo(destinationFile); | |
return fi; | |
} | |
} | |
return null; | |
} | |
catch (Exception e) | |
{ | |
Console.WriteLine(e.Message); | |
return null; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment