using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; using System.Web; using Neo.Afx.Services.Documents; namespace Neo.Afx.Services { /// /// Summary description for DocumentViewer /// public class DocumentViewer : IHttpHandler { readonly DocumentsDatabase _database = new DocumentsDatabase(); public void ProcessRequest(HttpContext context) { var isReadOnly = false; if(!String.IsNullOrEmpty(context.Request.QueryString["readOnly"])) { if(!bool.TryParse(context.Request.QueryString["readOnly"], out isReadOnly)) { isReadOnly = false; } } if(String.IsNullOrEmpty(context.Request.QueryString["documentID"])) return; long documentID; if(!Int64.TryParse(context.Request.QueryString["documentID"], out documentID)) { return; } var docObject = _database.GetDocumentObject(documentID); if(docObject == null) { return; } var isDownload = true; if(context.Request.QueryString["download"] != null) { bool.TryParse(context.Request.QueryString["download"], out isDownload); } var isThumbnail = false; if (context.Request.QueryString["thumbnail"] != null) { bool.TryParse(context.Request.QueryString["thumbnail"], out isThumbnail); } var thumbnailWidth = 160; if (context.Request.QueryString["thumbnailWidth"] != null) { int.TryParse(context.Request.QueryString["thumbnailWidth"], out thumbnailWidth); } var thumbnailHeight = 120; if (context.Request.QueryString["thumbnailHeight"] != null) { int.TryParse(context.Request.QueryString["thumbnailHeight"], out thumbnailHeight); } var showPhotoDate = false; if (context.Request.QueryString["showPhotoDate"] != null) { bool.TryParse(context.Request.QueryString["showPhotoDate"], out showPhotoDate); } var photoDateFont = new Font("Microsoft Sans Serif", 20F, FontStyle.Regular, GraphicsUnit.Point, 0); var photoDateFontThumbnail = new Font("Microsoft Sans Serif", 32F, FontStyle.Regular, GraphicsUnit.Point, 0); try { Image.FromStream(new MemoryStream(docObject.Content)); } catch (Exception) { showPhotoDate = false; isThumbnail = false; } if(!String.IsNullOrEmpty(docObject.Uri) && !isReadOnly) { context.Response.Redirect(docObject.Uri); } else { if (isThumbnail && showPhotoDate) { var memoryStream = new MemoryStream(docObject.Content); var fromStream = Image.FromStream(memoryStream); var image = new Bitmap(fromStream.Width, fromStream.Height + 70); var graphics = Graphics.FromImage(image); graphics.DrawImageUnscaled(fromStream, 0, 70); graphics.DrawString(GetPhotoTakenDate(fromStream), photoDateFontThumbnail, Brushes.White, new RectangleF(0, 0, fromStream.Width, 70)); var thumbnail = GetImageByteArray(image.GetThumbnailImage(thumbnailWidth, thumbnailHeight + (thumbnailHeight / 8), null, new IntPtr())); context.Response.ClearHeaders(); context.Response.ClearContent(); if (isDownload) { context.Response.AddHeader("Content-Disposition", " attachment; filename=" + docObject.Name); } else { context.Response.AddHeader("Content-Disposition", " inline; filename=" + docObject.Name); } context.Response.AddHeader("Content-Length", thumbnail.Length.ToString()); context.Response.ContentType = docObject.MimeType; context.Response.Charset = "UTF-8"; context.Response.BinaryWrite(thumbnail); if (context.Response.IsClientConnected) { context.Response.Flush(); context.Response.Clear(); } } else if (isThumbnail) { var memoryStream = new MemoryStream(docObject.Content); var fromStream = Image.FromStream(memoryStream); var thumbnailImage = fromStream.GetThumbnailImage(thumbnailWidth, thumbnailHeight, null, new IntPtr()); var thumbnail = GetImageByteArray(thumbnailImage); context.Response.ClearHeaders(); context.Response.ClearContent(); if (isDownload) { context.Response.AddHeader("Content-Disposition", " attachment; filename=" + docObject.Name); } else { context.Response.AddHeader("Content-Disposition", " inline; filename=" + docObject.Name); } context.Response.AddHeader("Content-Length", thumbnail.Length.ToString()); context.Response.ContentType = docObject.MimeType; context.Response.Charset = "UTF-8"; context.Response.BinaryWrite(thumbnail); if (context.Response.IsClientConnected) { context.Response.Flush(); context.Response.Clear(); } } else if (showPhotoDate) { var memoryStream = new MemoryStream(docObject.Content); var fromStream = Image.FromStream(memoryStream); var image = new Bitmap(fromStream.Width, fromStream.Height + 35); var graphics = Graphics.FromImage(image); graphics.DrawImage(fromStream, 0, 35, fromStream.Width, fromStream.Height); graphics.DrawString(GetPhotoTakenDate(fromStream), photoDateFont, Brushes.White, new RectangleF(0, 0, fromStream.Width, 35)); var imageByteArray = GetImageByteArray(image); context.Response.ClearHeaders(); context.Response.ClearContent(); if (isDownload) { context.Response.AddHeader("Content-Disposition", " attachment; filename=" + docObject.Name); } else { context.Response.AddHeader("Content-Disposition", " inline; filename=" + docObject.Name); } context.Response.AddHeader("Content-Length", imageByteArray.Length.ToString()); context.Response.ContentType = docObject.MimeType; context.Response.Charset = "UTF-8"; context.Response.BinaryWrite(imageByteArray); if (context.Response.IsClientConnected) { context.Response.Flush(); context.Response.Clear(); } } else { context.Response.ClearHeaders(); context.Response.ClearContent(); if (isDownload) { context.Response.AddHeader("Content-Disposition", " attachment; filename=" + docObject.Name); } else { context.Response.AddHeader("Content-Disposition", " inline; filename=" + docObject.Name); } context.Response.AddHeader("Content-Length", docObject.Length.ToString()); context.Response.ContentType = docObject.MimeType; context.Response.Charset = "UTF-8"; context.Response.BinaryWrite(docObject.Content); if (context.Response.IsClientConnected) { context.Response.Flush(); context.Response.Clear(); } } } } protected string GetPhotoTakenDate(Image image) { string dateTaken; const int propertyTagExifDtDigitized = 0x9004; var img = image; try { var item = img.GetPropertyItem(propertyTagExifDtDigitized); var dataTakenTime = Encoding.ASCII.GetString(item.Value); dateTaken = dataTakenTime; } catch (Exception) { dateTaken = "N/A"; } return "Date Taken: " + dateTaken; } protected byte[] GetImageByteArray(Image image) { byte[] returnData; using (var memoryStream = new MemoryStream()) { image.Save(memoryStream, ImageFormat.Jpeg); returnData = memoryStream.ToArray(); } return returnData; } public bool IsReusable { get { return false; } } } }