I found a nice code to down size image on server, to avoid bad image rendering by different browser. This code is for MVC application.
我找到了一个很好的代码来缩小服务器上的图像大小,以避免不同浏览器的不良图像渲染。此代码适用于MVC应用程序。
I have no experience in C# would like to know what do I need to change to make this code work in webforms.
我没有C#的经验想知道我需要改变什么来使这个代码在webforms中工作。
<img src="@Url.Action("ResizeImage", "Controller", new { urlImage = "<url_image>", width = 35 })" />
public ActionResult ResizeImage(string imageUrl, int width)
{
WebImage wImage = new WebImage(imageUrl);
wImage = WebImageExtension.Resize(wImage, width);
return File(wImage.GetBytes(), "image/png");
}
public static class WebImageExtension
{
private static readonly IDictionary<string, ImageFormat> TransparencyFormats =
new Dictionary<string, ImageFormat>(StringComparer.OrdinalIgnoreCase) { { "png", ImageFormat.Png }, { "gif", ImageFormat.Gif } };
public static WebImage Resize(this WebImage image, int width)
{
double aspectRatio = (double)image.Width / image.Height;
var height = Convert.ToInt32(width / aspectRatio);
ImageFormat format;
if (!TransparencyFormats.TryGetValue(image.ImageFormat.ToLower(), out format))
{
return image.Resize(width, height);
}
using (Image resizedImage = new Bitmap(width, height))
{
using (var source = new Bitmap(new MemoryStream(image.GetBytes())))
{
using (Graphics g = Graphics.FromImage(resizedImage))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(source, 0, 0, width, height);
}
}
using (var ms = new MemoryStream())
{
resizedImage.Save(ms, format);
return new WebImage(ms.ToArray());
}
}
}
}
UPDATE:
更新:
I use this code to resize images
我使用此代码来调整图像大小
public static void ResizeImageFreeSize(string OriginalFile, string NewFile, int MinWidth, int MinHeight, string FileExtension)
{
var NewHeight = MinHeight;
var NewWidth = MinWidth;
// var OriginalImage = System.Drawing.Image.FromFile(OriginalFile); // THis statlement alon with generate error as file is locked so -->GDI+ keeps a lock on files from which an image was contructed. To avoid the lock, construct the image from a MemorySteam:
MemoryStream ms = new MemoryStream(File.ReadAllBytes(OriginalFile));
var OriginalImage = System.Drawing.Image.FromStream(ms);
if (OriginalImage.Width < MinWidth || OriginalImage.Height < MinHeight)
throw new Exception(String.Format("Invalid Image Dimensions, please upload an image with minmum dimensions of {0}x{1}px", MinWidth.ToString(), MinHeight.ToString()));
// If the image dimensions are the same then make the new dimensions the largest of the two mins.
if (OriginalImage.Height == OriginalImage.Width)
NewWidth = NewHeight = (MinWidth > MinHeight) ? MinWidth : MinHeight;
else
{
if (MinWidth > MinHeight)
NewHeight = (int)(OriginalImage.Height * ((float)MinWidth / (float)OriginalImage.Width));
else
NewWidth = (int)(OriginalImage.Width * ((float)MinHeight / (float)OriginalImage.Height));
}
// Just resample the Original Image into a new Bitmap
var ResizedBitmap = new System.Drawing.Bitmap(OriginalImage, NewWidth, NewHeight);
// Saves the new bitmap in the same format as it's source image
FileExtension = FileExtension.ToLower().Replace(".", "");
ImageFormat Format = null;
switch (FileExtension)
{
case "jpg":
Format = ImageFormat.Jpeg;
Encoder quality = Encoder.Quality;
var ratio = new EncoderParameter(quality, 100L);
var codecParams = new EncoderParameters(1);
codecParams.Param[0] = ratio;
// NewImage.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
ResizedBitmap.Save(NewFile, GetEncoder(ImageFormat.Jpeg), codecParams);
break;
case "gif":
Format = ImageFormat.Gif;
ResizedBitmap.Save(NewFile, Format);
break;
case "png":
Format = ImageFormat.Png;
ResizedBitmap.Save(NewFile, Format);
break;
default:
Format = ImageFormat.Png;
ResizedBitmap.Save(NewFile, Format);
break;
}
// ResizedBitmap.Save(NewFile, Format);
// Clear handle to original file so that we can overwrite it if necessary
OriginalImage.Dispose();
ResizedBitmap.Dispose();
}
1 个解决方案
#1
1
You can have a HttpHandler
for this in C#,
你可以在C#中使用HttpHandler,
namespace CMSN.Software.Tutorials.HowToDynamicallyResizeImages
{
public class DynamicImage : IHttpHandler
{
/// <summary>
/// Default cache duration
/// </summary>
private static readonly TimeSpan CacheDuration = TimeSpan.FromDays(30);
/// <summary>
/// Gets a value indicating whether another request can use the
/// <see cref="T:System.Web.IHttpHandler"/> instance.
/// </summary>
/// <returns>
/// true if the <see cref="T:System.Web.IHttpHandler"/> instance is reusable; otherwise, false.
/// </returns>
public bool IsReusable
{
get
{
return false;
}
}
/// <summary>
/// Enables processing of HTTP Web requests by a custom HttpHandler that implements the
/// <see cref="T:System.Web.IHttpHandler"/> interface.
/// </summary>
/// <param name="context">An <see cref="T:System.Web.HttpContext"/> object that provides references to the
/// intrinsic server objects (for example, Request, Response, Session, and Server)
/// used to service HTTP requests.
/// </param>
public void ProcessRequest(HttpContext context)
{
string cacheKeyName = context.Request.Url.PathAndQuery;
string imagePath = context.Server.MapPath(context.Request.Url.LocalPath);
string imageExtention = Path.GetExtension(imagePath);
string contentType = string.Empty;
byte[] imageFileContent;
ImageFormat imageFormat = null;
switch (imageExtention)
{
case ".png":
imageFormat = ImageFormat.Png;
contentType = "image/png";
break;
case ".jpg":
case ".jpeg":
case ".jpe":
imageFormat = ImageFormat.Jpeg;
contentType = "image/jpeg";
break;
case ".bmp":
imageFormat = ImageFormat.Bmp;
contentType = "image/bmp";
break;
case ".gif":
imageFormat = ImageFormat.Gif;
contentType = "image/gif";
break;
default:
break;
}
context.Response.ContentType = contentType;
if (context.Cache[CacheKey(cacheKeyName)] != null)
{
imageFileContent = context.Cache[CacheKey(cacheKeyName)] as byte[];
}
else
{
int imageWidth = 0;
int imageHeight = 0;
if (!string.IsNullOrEmpty(context.Request["w"]))
{
if (!int.TryParse(context.Request["w"], out imageWidth))
{
imageWidth = 0;
}
}
if (!string.IsNullOrEmpty(context.Request["h"]))
{
if (!int.TryParse(context.Request["h"], out imageHeight))
{
imageHeight = 0;
}
}
Image originalImage;
if (File.Exists(imagePath))
{
originalImage = Image.FromFile(imagePath);
}
else
{
originalImage = new Bitmap(100, 100);
}
if (imageWidth > 0 || imageHeight > 0)
{
if (imageHeight == 0 && imageWidth > 0)
{
imageHeight = originalImage.Height * imageWidth / originalImage.Width;
}
if (imageWidth == 0 && imageHeight > 0)
{
imageWidth = originalImage.Width * imageHeight / originalImage.Height;
}
}
else
{
imageHeight = originalImage.Height;
imageWidth = originalImage.Width;
}
using (Bitmap newImage = new Bitmap(originalImage, imageWidth, imageHeight))
{
Graphics generatedImage = Graphics.FromImage(newImage);
generatedImage.InterpolationMode = InterpolationMode.HighQualityBicubic;
generatedImage.SmoothingMode = SmoothingMode.AntiAlias;
generatedImage.CompositingQuality = CompositingQuality.HighQuality;
generatedImage.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
// make a memory stream to work with the image bytes
using (MemoryStream imageStream = new MemoryStream())
{
// put the image into the memory stream
newImage.Save(imageStream, imageFormat);
// make byte array the same size as the image
byte[] imageContent = new byte[imageStream.Length];
// rewind the memory stream
imageStream.Position = 0;
// load the byte array with the image
imageStream.Read(imageContent, 0, (int)imageStream.Length);
// return byte array to caller with image type
imageFileContent = imageContent;
using (CacheDependency dependency = new CacheDependency(imagePath))
{
context.Cache.Insert(
CacheKey(cacheKeyName),
imageContent,
dependency,
System.Web.Caching.Cache.NoAbsoluteExpiration,
CacheDuration);
}
}
}
originalImage.Dispose();
}
SetResponseCache(context.Response, new string[1] { imagePath });
context.Response.BinaryWrite(imageFileContent);
}
/// <summary>
/// Generate unique Cache key.
/// </summary>
/// <param name="key">The cache key.</param>
/// <returns>Generated unique Cache key</returns>
protected static string CacheKey(string key)
{
return "DynamicImage." + key;
}
/// <summary>
/// Sets the response cache.
/// </summary>
/// <param name="response">The response.</param>
/// <param name="files">The files.</param>
protected static void SetResponseCache(HttpResponse response, string[] files)
{
response.AddFileDependencies(files);
HttpCachePolicy browserCache = response.Cache;
DateTime modifiedTime = DateTime.Now;
browserCache.SetCacheability(HttpCacheability.ServerAndPrivate);
browserCache.VaryByParams["w"] = true;
browserCache.VaryByParams["h"] = true;
browserCache.VaryByParams["v"] = true;
browserCache.SetOmitVaryStar(true);
browserCache.SetExpires(modifiedTime.AddDays(7));
browserCache.SetValidUntilExpires(true);
browserCache.SetLastModified(modifiedTime);
browserCache.SetETagFromFileDependencies();
browserCache.SetLastModifiedFromFileDependencies();
}
}
}
Web.config
Web.config文件
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpHandlers>
<add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" name="DynamicImage" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
</handlers>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>
Usage,
用法,
http://localhost/Images/xxxxxxxx.png?w=300&h=149
If you want to see the complete guide for this, please follow the following URL.
如果您想查看完整的指南,请访问以下网址。
http://tutorials.cmsnsoftware.com/2011/09/how-to-dynamically-resize-images.html
http://tutorials.cmsnsoftware.com/2011/09/how-to-dynamically-resize-images.html
#1
1
You can have a HttpHandler
for this in C#,
你可以在C#中使用HttpHandler,
namespace CMSN.Software.Tutorials.HowToDynamicallyResizeImages
{
public class DynamicImage : IHttpHandler
{
/// <summary>
/// Default cache duration
/// </summary>
private static readonly TimeSpan CacheDuration = TimeSpan.FromDays(30);
/// <summary>
/// Gets a value indicating whether another request can use the
/// <see cref="T:System.Web.IHttpHandler"/> instance.
/// </summary>
/// <returns>
/// true if the <see cref="T:System.Web.IHttpHandler"/> instance is reusable; otherwise, false.
/// </returns>
public bool IsReusable
{
get
{
return false;
}
}
/// <summary>
/// Enables processing of HTTP Web requests by a custom HttpHandler that implements the
/// <see cref="T:System.Web.IHttpHandler"/> interface.
/// </summary>
/// <param name="context">An <see cref="T:System.Web.HttpContext"/> object that provides references to the
/// intrinsic server objects (for example, Request, Response, Session, and Server)
/// used to service HTTP requests.
/// </param>
public void ProcessRequest(HttpContext context)
{
string cacheKeyName = context.Request.Url.PathAndQuery;
string imagePath = context.Server.MapPath(context.Request.Url.LocalPath);
string imageExtention = Path.GetExtension(imagePath);
string contentType = string.Empty;
byte[] imageFileContent;
ImageFormat imageFormat = null;
switch (imageExtention)
{
case ".png":
imageFormat = ImageFormat.Png;
contentType = "image/png";
break;
case ".jpg":
case ".jpeg":
case ".jpe":
imageFormat = ImageFormat.Jpeg;
contentType = "image/jpeg";
break;
case ".bmp":
imageFormat = ImageFormat.Bmp;
contentType = "image/bmp";
break;
case ".gif":
imageFormat = ImageFormat.Gif;
contentType = "image/gif";
break;
default:
break;
}
context.Response.ContentType = contentType;
if (context.Cache[CacheKey(cacheKeyName)] != null)
{
imageFileContent = context.Cache[CacheKey(cacheKeyName)] as byte[];
}
else
{
int imageWidth = 0;
int imageHeight = 0;
if (!string.IsNullOrEmpty(context.Request["w"]))
{
if (!int.TryParse(context.Request["w"], out imageWidth))
{
imageWidth = 0;
}
}
if (!string.IsNullOrEmpty(context.Request["h"]))
{
if (!int.TryParse(context.Request["h"], out imageHeight))
{
imageHeight = 0;
}
}
Image originalImage;
if (File.Exists(imagePath))
{
originalImage = Image.FromFile(imagePath);
}
else
{
originalImage = new Bitmap(100, 100);
}
if (imageWidth > 0 || imageHeight > 0)
{
if (imageHeight == 0 && imageWidth > 0)
{
imageHeight = originalImage.Height * imageWidth / originalImage.Width;
}
if (imageWidth == 0 && imageHeight > 0)
{
imageWidth = originalImage.Width * imageHeight / originalImage.Height;
}
}
else
{
imageHeight = originalImage.Height;
imageWidth = originalImage.Width;
}
using (Bitmap newImage = new Bitmap(originalImage, imageWidth, imageHeight))
{
Graphics generatedImage = Graphics.FromImage(newImage);
generatedImage.InterpolationMode = InterpolationMode.HighQualityBicubic;
generatedImage.SmoothingMode = SmoothingMode.AntiAlias;
generatedImage.CompositingQuality = CompositingQuality.HighQuality;
generatedImage.DrawImage(originalImage, 0, 0, newImage.Width, newImage.Height);
// make a memory stream to work with the image bytes
using (MemoryStream imageStream = new MemoryStream())
{
// put the image into the memory stream
newImage.Save(imageStream, imageFormat);
// make byte array the same size as the image
byte[] imageContent = new byte[imageStream.Length];
// rewind the memory stream
imageStream.Position = 0;
// load the byte array with the image
imageStream.Read(imageContent, 0, (int)imageStream.Length);
// return byte array to caller with image type
imageFileContent = imageContent;
using (CacheDependency dependency = new CacheDependency(imagePath))
{
context.Cache.Insert(
CacheKey(cacheKeyName),
imageContent,
dependency,
System.Web.Caching.Cache.NoAbsoluteExpiration,
CacheDuration);
}
}
}
originalImage.Dispose();
}
SetResponseCache(context.Response, new string[1] { imagePath });
context.Response.BinaryWrite(imageFileContent);
}
/// <summary>
/// Generate unique Cache key.
/// </summary>
/// <param name="key">The cache key.</param>
/// <returns>Generated unique Cache key</returns>
protected static string CacheKey(string key)
{
return "DynamicImage." + key;
}
/// <summary>
/// Sets the response cache.
/// </summary>
/// <param name="response">The response.</param>
/// <param name="files">The files.</param>
protected static void SetResponseCache(HttpResponse response, string[] files)
{
response.AddFileDependencies(files);
HttpCachePolicy browserCache = response.Cache;
DateTime modifiedTime = DateTime.Now;
browserCache.SetCacheability(HttpCacheability.ServerAndPrivate);
browserCache.VaryByParams["w"] = true;
browserCache.VaryByParams["h"] = true;
browserCache.VaryByParams["v"] = true;
browserCache.SetOmitVaryStar(true);
browserCache.SetExpires(modifiedTime.AddDays(7));
browserCache.SetValidUntilExpires(true);
browserCache.SetLastModified(modifiedTime);
browserCache.SetETagFromFileDependencies();
browserCache.SetLastModifiedFromFileDependencies();
}
}
}
Web.config
Web.config文件
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpHandlers>
<add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<add verb="*" path="*.png,*.jpg,*.jpeg,*.gif,*.bmp" name="DynamicImage" type="CMSN.Software.Tutorials.HowToDynamicallyResizeImages.DynamicImage,HowToDynamicallyResizeImages"/>
</handlers>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>
Usage,
用法,
http://localhost/Images/xxxxxxxx.png?w=300&h=149
If you want to see the complete guide for this, please follow the following URL.
如果您想查看完整的指南,请访问以下网址。
http://tutorials.cmsnsoftware.com/2011/09/how-to-dynamically-resize-images.html
http://tutorials.cmsnsoftware.com/2011/09/how-to-dynamically-resize-images.html