Створення маленької картинки (thumbnail images)

79

Програмування Asp.net
Попередній

Наступний

Часто виникає потреба показувати велику картинку, але зменшивши її розмір і що б при цьому зберігалося її якість. Стандартний метод не підходить

Тоді я пропоную створювати IHttpHandler і за допомогою нього робити перетворення. У Handler я буду get-запиту передавати адресу до картинки. Але як завжди не все так просто. Є два шляхи вирішення проблеми. Перший метод підходить якщо на виході ми хочемо отримати дуже маленьку картинку

У параметр PhotoIMG – шлях до зображення, розмір вихідний картинка на 100 100

Code

using System;
using System.Web;
using System.Drawing;

public class PhotoSmall: IHttpHandler {
public void ProcessRequest (HttpContext context) {
Bitmap test;
try
{test = new Bitmap(context.Request.QueryString[«PhotoIMG»]); }
catch
{ test = new Bitmap(«noimage.jpg»);}

System.Drawing.Image.GetThumbnailImageAbort myCallback =
new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback);

int width = 100;
int height = 100;

Bitmap holst = new Bitmap(width, height);
Graphics ImageGraphics = Graphics.FromImage(holst);

Image photo = test.GetThumbnailImage(width, height, myCallback, IntPtr.Zero);
ImageGraphics.DrawImage(photo, 0, 0, photo.Width, photo.Height);

using System.IO.MemoryStream stmMemory = new System.IO.MemoryStream())
{
context.Response.Clear();
context.Response.ContentType = «image/jpeg»;
holst.Save(stmMemory, System.Drawing.Imaging.ImageFormat.Png);
stmMemory.WriteTo(context.Response.OutputStream);
context.Response.End();
}

ImageGraphics.Dispose();
}

public static bool ThumbnailCallback()
{
return false;
}

public bool IsReusable {
get {
return false;
}
}
}

Наступний метод якщо картинка не багато більше розміру наприклад 300 на 300

Code

using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;

public class PhotoSmall : IHttpHandler
{
private static ImageCodecInfo getCodecInfo(string mt)
{
ImageCodecInfo[] ici = ImageCodecInfo.GetImageEncoders();
int idx = 0;
for (int ii = 0; ii < ici.Length; ii++)
{
if (ici[ii].MimeType == mt)
{
idx = ii;
break;
}
}
return ici[idx];
}

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = «image/jpeg»;
context.Response.Clear();

System.Drawing.Image g;
try
{
g = System.Drawing.Image.FromFile(context.Request.QueryString[«PhotoIMG»]);
}
catch
{
g = System.Drawing.Image.FromFile(«noimage.jpg»);
}

int width = 300;
int height = 300;

Bitmap b = new Bitmap(width, height);

Graphics gTemp = Graphics.FromImage(b);
gTemp.InterpolationMode = InterpolationMode.Bicubic;
gTemp.PixelOffsetMode = PixelOffsetMode.HighQuality;
gTemp.DrawImage(g, 0, 0, width, height);

EncoderParameters ep = new EncoderParameters(1);
ImageCodecInfo icJPG = getCodecInfo(«image/jpeg»);

ep.Param[0] = new EncoderParameter(Encoder.Quality, (long)80);

b.Save(context.Response.OutputStream, icJPG, ep);

gTemp.Dispose();
b.Dispose();
g.Dispose();
}

public bool IsReusable {
get {
return false;
}}}

Ще цей код можна додати пропорційне зміна розміру картинки. Тобто якщо картинка була 100х200, то після зміни вона залишилася 50х100

Code

int ReqWidth = 0;
int ReqHeight = 0;

bool result = int.TryParse(context.Request.Params[«Width»], out ReqWidth);
int defaultWidth = 100;
if (result)
defaultWidth = ReqWidth;

int defaultHeight = 100;
result = int.TryParse(context.Request.Params[«Height»], out ReqHeight);
if (result)
defaultHeight = ReqHeight;

int width = 0;
int height = 0;

if (defaultWidth > g.Width) defaultWidth = g.Width;
else if (defaultHeight > g.Height) defaultHeight = g.Height;
float x = (float)g.Width / (float)defaultWidth;
float y = (float)g.Height / (float)defaultHeight;

if (x > y)
{
width = (int)(g.Width / x);
height = (int)(g.Height / x);
}
else
{
width = (int)(g.Width / y);
height = (int)(g.Height / y);
}