1

我找到了一个很好的代码来缩小服务器上的图像大小,以避免不同浏览器的不良图像渲染。此代码适用于 MVC 应用程序。

我没有 C# 经验想知道我需要更改什么才能使此代码在 web 表单中工作。

<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());
            }
        }
    }
}

更新:

我使用此代码调整图像大小

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();
}
4

1 回答 1

1

你可以HttpHandler在 C# 中有一个为此,

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();
        }
    }
}

网页配置

<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>

用法,

http://localhost/Images/xxxxxxxx.png?w=300&h=149

如果您想查看完整指南,请访问以下 URL。

http://tutorials.cmsnsoftware.com/2011/09/how-to-dynamically-resize-images.html

于 2013-09-11T06:46:10.513 回答