using System; using Microsoft.SharePoint; using Microsoft.SharePoint.WebControls; using System.Linq; namespace QuarterlyAward { public partial class Thumbnail : LayoutsPageBase { /// <summary> /// Create thumbnail for list attachment /// Query string parameters: /// listID: List id /// itemID: Item id of list /// w: Specified thumbnail width /// h: Specified thumbnail height /// c: Use cache if cache exist and parameter value is not set /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Page_Load(object sender, EventArgs e) { string cacheID = string.Format("{0}#{1}#{2}#{3}", Request.QueryString["listID"], Request.QueryString["itemID"], Request.QueryString["w"], Request.QueryString["h"]); byte[] thumbnailBinary = null; // Cache detection if (string.IsNullOrEmpty(Request.QueryString["c"]) && Cache[cacheID] != null) { thumbnailBinary = Cache[cacheID] as byte[]; // Output cached thumbnail Response.Clear(); Response.OutputStream.Write(thumbnailBinary, 0, thumbnailBinary.Length); Response.ContentType = "image/png"; Response.End(); return; } // Lack of parameter if (string.IsNullOrEmpty(Request.QueryString["listID"]) || string.IsNullOrEmpty(Request.QueryString["itemID"])) { Response.StatusCode = 404; return; } // Validate parameter int itemID = -1; if (!int.TryParse(Request.QueryString["itemID"], out itemID)) { Response.StatusCode = 404; return; } int width = -1, height = -1; int.TryParse(Request.QueryString["w"], out width); int.TryParse(Request.QueryString["h"], out height); if (width == -1 && height == -1) { Response.StatusCode = 404; return; } #region Get attachment and generate thumbnail using (var web = SPContext.Current.Site.OpenWeb()) { var list = web.Lists[new Guid(Request.QueryString["listID"])]; var item = list.GetItemById(itemID); if (item == null || item.Attachments == null || item.Attachments.Count == 0) { Response.StatusCode = 404; return; } var imageType = new string[] { ".jpg", ".jpeg", ".gif", ".png", ".bmp" }; // Get attachment folder var folder = item.ParentList.RootFolder.SubFolders["Attachments"].SubFolders[item.ID.ToString()]; // Get image attachment var files = folder.Files .OfType<SPFile>() .Where(f => imageType.Contains(System.IO.Path.GetExtension(f.ServerRelativeUrl.ToLower()))); if (!files.Any()) { Response.StatusCode = 404; return; } var file = files.First(); // Open image binary in memory var ms = new System.IO.MemoryStream(file.OpenBinary()); // Load image instance var source = System.Drawing.Image.FromStream(ms); // Limit width & height if (source.Width < width || width < 1) width = source.Width; if (source.Height < height || height < 1) height = source.Height; var size = adaptProportionalSize(new System.Drawing.Size(width, height), source.Size); // Create thumbnail var thumbnailImage = source.GetThumbnailImage(size.Width, size.Height, null, IntPtr.Zero); // Get thumbnail binary ms = new System.IO.MemoryStream(); thumbnailImage.Save(ms, System.Drawing.Imaging.ImageFormat.Png); thumbnailBinary = ms.ToArray(); // Cache 30 min Cache.Add( cacheID, thumbnailBinary, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), System.Web.Caching.CacheItemPriority.High, null); } #endregion // Output thumbnail Response.Clear(); Response.OutputStream.Write(thumbnailBinary, 0, thumbnailBinary.Length); Response.ContentType = "image/png"; Response.End(); } /// <summary> /// Caculate appropriate size for thumbnail /// </summary> /// <param name="szMax"></param> /// <param name="szReal"></param> /// <returns></returns> System.Drawing.Size adaptProportionalSize(System.Drawing.Size szMax, System.Drawing.Size szReal) { int nWidth; int nHeight; double sMaxRatio; double sRealRatio; if (szMax.Width < 1 || szMax.Height < 1 || szReal.Width < 1 || szReal.Height < 1) return System.Drawing.Size.Empty; sMaxRatio = (double)szMax.Width / (double)szMax.Height; sRealRatio = (double)szReal.Width / (double)szReal.Height; if (sMaxRatio < sRealRatio) { nWidth = Math.Min(szMax.Width, szReal.Width); nHeight = (int)Math.Round(nWidth / sRealRatio); } else { nHeight = Math.Min(szMax.Height, szReal.Height); nWidth = (int)Math.Round(nHeight * sRealRatio); } return new System.Drawing.Size(nWidth, nHeight); } } }