Generate thumbnail for list attachment
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);
}
}
}