调整图像大小C#

由于SizeWidthHeight是System.Drawing.Image的Get()属性,
如何在C#中运行时调整Image对象的大小

现在,我只是创build一个新的Image使用:

 // objImage is the original Image Bitmap objBitmap = new Bitmap(objImage, new Size(227, 171)); 

这将执行高品质的resize:

 /// <summary> /// Resize the image to the specified width and height. /// </summary> /// <param name="image">The image to resize.</param> /// <param name="width">The width to resize to.</param> /// <param name="height">The height to resize to.</param> /// <returns>The resized image.</returns> public static Bitmap ResizeImage(Image image, int width, int height) { var destRect = new Rectangle(0, 0, width, height); var destImage = new Bitmap(width, height); destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (var graphics = Graphics.FromImage(destImage)) { graphics.CompositingMode = CompositingMode.SourceCopy; graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; using (var wrapMode = new ImageAttributes()) { wrapMode.SetWrapMode(WrapMode.TileFlipXY); graphics.DrawImage(image, destRect, 0, 0, image.Width,image.Height, GraphicsUnit.Pixel, wrapMode); } } return destImage; } 
  • wrapMode.SetWrapMode(WrapMode.TileFlipXY)可以防止图像边界出现重影 – 天真的resize将会在图像边界之外对透明像素进行采样,但是通过对图像进行镜像,我们可以得到更好的样本(这个设置非常明显)
  • destImage.SetResolution保留DPI而不考虑物理尺寸 – 在缩小图像尺寸或打印时可能会提高质量
  • 合成控制像素如何与背景混合 – 可能不需要,因为我们只绘制一个东西。
    • graphics.CompositingMode确定来自源图像的像素是否覆盖或与背景像素组合。 SourceCopy指定在呈现颜色时覆盖背景颜色。
    • graphics.CompositingQuality决定了分层图像的渲染质量级别。
  • graphics.InterpolationMode确定如何计算两个端点之间的中间值
  • graphics.SmoothingMode指定线条,曲线和填充区域的边缘是否使用平滑(也称为抗锯齿) – 可能只适用于vector
  • graphics.PixelOffsetMode在绘制新图像时会影响渲染质量

保持宽高比作为读者的练习(实际上,我只是不认为这是为你做这个function的工作)。

此外, 这是一个很好的文章,描述了图像大小调整的一些陷阱。 上述function将覆盖大部分function,但您仍然需要考虑保存 。

不知道什么是这么难,做你在做什么,使用重载的位图构造函数来创build一个重新大小的图像,你唯一缺less的是转换回图像数据types:

  public static Image resizeImage(Image imgToResize, Size size) { return (Image)(new Bitmap(imgToResize, size)); } yourImage = resizeImage(yourImage, new Size(50,50)); 

在这个问题中 ,你会有一些答案,包括我的:

 public Image resizeImage(int newWidth, int newHeight, string stPhotoPath) { Image imgPhoto = Image.FromFile(stPhotoPath); int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; //Consider vertical pics if (sourceWidth < sourceHeight) { int buff = newWidth; newWidth = newHeight; newHeight = buff; } int sourceX = 0, sourceY = 0, destX = 0, destY = 0; float nPercent = 0, nPercentW = 0, nPercentH = 0; nPercentW = ((float)newWidth / (float)sourceWidth); nPercentH = ((float)newHeight / (float)sourceHeight); if (nPercentH < nPercentW) { nPercent = nPercentH; destX = System.Convert.ToInt16((newWidth - (sourceWidth * nPercent)) / 2); } else { nPercent = nPercentW; destY = System.Convert.ToInt16((newHeight - (sourceHeight * nPercent)) / 2); } int destWidth = (int)(sourceWidth * nPercent); int destHeight = (int)(sourceHeight * nPercent); Bitmap bmPhoto = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb); bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); Graphics grPhoto = Graphics.FromImage(bmPhoto); grPhoto.Clear(Color.Black); grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; grPhoto.DrawImage(imgPhoto, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel); grPhoto.Dispose(); imgPhoto.Dispose(); return bmPhoto; } 

为什么不使用System.Drawing.Image.GetThumbnailImage方法?

 public Image GetThumbnailImage( int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort callback, IntPtr callbackData) 

例:

 Image originalImage = System.Drawing.Image.FromStream(inputStream, true, true); Image resizedImage = originalImage.GetThumbnailImage(newWidth, (newWidth * originalImage.Height) / originalWidth, null, IntPtr.Zero); resizedImage.Save(imagePath, ImageFormat.Png); 

来源: http : //msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx

这会 –

  • 调整宽度和高度,无需循环
  • 不超过图像的原始尺寸

//////////////

 private void ResizeImage(Image img, double maxWidth, double maxHeight) { double resizeWidth = img.Source.Width; double resizeHeight = img.Source.Height; double aspect = resizeWidth / resizeHeight; if (resizeWidth > maxWidth) { resizeWidth = maxWidth; resizeHeight = resizeWidth / aspect; } if (resizeHeight > maxHeight) { aspect = resizeWidth / resizeHeight; resizeHeight = maxHeight; resizeWidth = resizeHeight * aspect; } img.Width = resizeWidth; img.Height = resizeHeight; } 

在我做的应用程序中,有必要创build一个具有多个选项的函数。 这是相当大的,但它调整图像,可以保持长宽比,并可以削减的边缘只返回图像的中心:

 /// <summary> /// Resize image with a directory as source /// </summary> /// <param name="OriginalFileLocation">Image location</param> /// <param name="heigth">new height</param> /// <param name="width">new width</param> /// <param name="keepAspectRatio">keep the aspect ratio</param> /// <param name="getCenter">return the center bit of the image</param> /// <returns>image with new dimentions</returns> public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio, Boolean getCenter) { int newheigth = heigth; System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFileLocation); // Prevent using images internal thumbnail FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone); if (keepAspectRatio || getCenter) { int bmpY = 0; double resize = (double)FullsizeImage.Width / (double)width;//get the resize vector if (getCenter) { bmpY = (int)((FullsizeImage.Height - (heigth * resize)) / 2);// gives the Y value of the part that will be cut off, to show only the part in the center Rectangle section = new Rectangle(new Point(0, bmpY), new Size(FullsizeImage.Width, (int)(heigth * resize)));// create the section to cut of the original image //System.Console.WriteLine("the section that will be cut off: " + section.Size.ToString() + " the Y value is minimized by: " + bmpY); Bitmap orImg = new Bitmap((Bitmap)FullsizeImage);//for the correct effect convert image to bitmap. FullsizeImage.Dispose();//clear the original image using (Bitmap tempImg = new Bitmap(section.Width, section.Height)) { Graphics cutImg = Graphics.FromImage(tempImg);// set the file to save the new image to. cutImg.DrawImage(orImg, 0, 0, section, GraphicsUnit.Pixel);// cut the image and save it to tempImg FullsizeImage = tempImg;//save the tempImg as FullsizeImage for resizing later orImg.Dispose(); cutImg.Dispose(); return FullsizeImage.GetThumbnailImage(width, heigth, null, IntPtr.Zero); } } else newheigth = (int)(FullsizeImage.Height / resize);// set the new heigth of the current image }//return the image resized to the given heigth and width return FullsizeImage.GetThumbnailImage(width, newheigth, null, IntPtr.Zero); } 

为了使访问函数更容易,可以添加一些重载的函数:

 /// <summary> /// Resize image with a directory as source /// </summary> /// <param name="OriginalFileLocation">Image location</param> /// <param name="heigth">new height</param> /// <param name="width">new width</param> /// <returns>image with new dimentions</returns> public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width) { return resizeImageFromFile(OriginalFileLocation, heigth, width, false, false); } /// <summary> /// Resize image with a directory as source /// </summary> /// <param name="OriginalFileLocation">Image location</param> /// <param name="heigth">new height</param> /// <param name="width">new width</param> /// <param name="keepAspectRatio">keep the aspect ratio</param> /// <returns>image with new dimentions</returns> public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio) { return resizeImageFromFile(OriginalFileLocation, heigth, width, keepAspectRatio, false); } 

现在是可选的最后两个布尔值。 像这样调用函数:

 System.Drawing.Image ResizedImage = resizeImageFromFile(imageLocation, 800, 400, true, true); 
 public static Image resizeImage(Image image, int new_height, int new_width) { Bitmap new_image = new Bitmap(new_width, new_height); Graphics g = Graphics.FromImage((Image)new_image ); g.InterpolationMode = InterpolationMode.High; g.DrawImage(image, 0, 0, new_width, new_height); return new_image; } 
 public string CreateThumbnail(int maxWidth, int maxHeight, string path) { var image = System.Drawing.Image.FromFile(path); var ratioX = (double)maxWidth / image.Width; var ratioY = (double)maxHeight / image.Height; var ratio = Math.Min(ratioX, ratioY); var newWidth = (int)(image.Width * ratio); var newHeight = (int)(image.Height * ratio); var newImage = new Bitmap(newWidth, newHeight); Graphics thumbGraph = Graphics.FromImage(newImage); thumbGraph.CompositingQuality = CompositingQuality.HighQuality; thumbGraph.SmoothingMode = SmoothingMode.HighQuality; //thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic; thumbGraph.DrawImage(image, 0, 0, newWidth, newHeight); image.Dispose(); string fileRelativePath = "newsizeimages/" + maxWidth + Path.GetFileName(path); newImage.Save(Server.MapPath(fileRelativePath), newImage.RawFormat); return fileRelativePath; } 

点击这里http://bhupendrasinghsaini.blogspot.in/2014/07/resize-image-in-c.html

这是我为特定要求制定的代码,即:目的地始终处于横向比例。 它应该给你一个好的开始。

 public Image ResizeImage(Image source, RectangleF destinationBounds) { RectangleF sourceBounds = new RectangleF(0.0f,0.0f,(float)source.Width, (float)source.Height); RectangleF scaleBounds = new RectangleF(); Image destinationImage = new Bitmap((int)destinationBounds.Width, (int)destinationBounds.Height); Graphics graph = Graphics.FromImage(destinationImage); graph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Fill with background color graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), destinationBounds); float resizeRatio, sourceRatio; float scaleWidth, scaleHeight; sourceRatio = (float)source.Width / (float)source.Height; if (sourceRatio >= 1.0f) { //landscape resizeRatio = destinationBounds.Width / sourceBounds.Width; scaleWidth = destinationBounds.Width; scaleHeight = sourceBounds.Height * resizeRatio; float trimValue = destinationBounds.Height - scaleHeight; graph.DrawImage(source, 0, (trimValue / 2), destinationBounds.Width, scaleHeight); } else { //portrait resizeRatio = destinationBounds.Height/sourceBounds.Height; scaleWidth = sourceBounds.Width * resizeRatio; scaleHeight = destinationBounds.Height; float trimValue = destinationBounds.Width - scaleWidth; graph.DrawImage(source, (trimValue / 2), 0, scaleWidth, destinationBounds.Height); } return destinationImage; } 

如果您正在使用BitmapSource

 var resizedBitmap = new TransformedBitmap( bitmapSource, new ScaleTransform(scaleX, scaleY)); 

如果您想更好地控制质量,请首先运行:

 RenderOptions.SetBitmapScalingMode( bitmapSource, BitmapScalingMode.HighQuality); 

(默认是BitmapScalingMode.Linear ,相当于BitmapScalingMode.LowQuality 。)

我使用ImageProcessorCore,主要是因为它工作.Net核心。

它有更多的select,如转换types,裁剪图像和更多

http://imageprocessor.org/imageprocessor/

此代码是从上面的答案之一发布相同..但将转换透明像素为白色,而不是黑色…谢谢:)

  public Image resizeImage(int newWidth, int newHeight, string stPhotoPath) { Image imgPhoto = Image.FromFile(stPhotoPath); int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; //Consider vertical pics if (sourceWidth < sourceHeight) { int buff = newWidth; newWidth = newHeight; newHeight = buff; } int sourceX = 0, sourceY = 0, destX = 0, destY = 0; float nPercent = 0, nPercentW = 0, nPercentH = 0; nPercentW = ((float)newWidth / (float)sourceWidth); nPercentH = ((float)newHeight / (float)sourceHeight); if (nPercentH < nPercentW) { nPercent = nPercentH; destX = System.Convert.ToInt16((newWidth - (sourceWidth * nPercent)) / 2); } else { nPercent = nPercentW; destY = System.Convert.ToInt16((newHeight - (sourceHeight * nPercent)) / 2); } int destWidth = (int)(sourceWidth * nPercent); int destHeight = (int)(sourceHeight * nPercent); Bitmap bmPhoto = new Bitmap(newWidth, newHeight, PixelFormat.Format24bppRgb); bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); Graphics grPhoto = Graphics.FromImage(bmPhoto); grPhoto.Clear(Color.White); grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; grPhoto.DrawImage(imgPhoto, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel); grPhoto.Dispose(); imgPhoto.Dispose(); return bmPhoto; } 

您可以使用Accord.NET框架 。 它提供了一些resize的不同方法:

  • 双立方
  • 双线性
  • 最近的邻居

注意:这不适用于ASP.Net核心,因为WebImage依赖于System.Web,但是在以前的ASP.Net版本中,我多次使用了这个片段,并且非常有用。

 String ThumbfullPath = Path.GetFileNameWithoutExtension(file.FileName) + "80x80.jpg"; var ThumbfullPath2 = Path.Combine(ThumbfullPath, fileThumb); using (MemoryStream stream = new MemoryStream(System.IO.File.ReadAllBytes(fullPath))) { var thumbnail = new WebImage(stream).Resize(80, 80); thumbnail.Save(ThumbfullPath2, "jpg"); } 

resize和保存图像以适应宽度和高度,如同保持图像比例的canvas一样

 using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; namespace Infra.Files { public static class GenerateThumb { /// <summary> /// Resize and save an image to fit under width and height like a canvas keeping things proportional /// </summary> /// <param name="originalImagePath"></param> /// <param name="thumbImagePath"></param> /// <param name="newWidth"></param> /// <param name="newHeight"></param> public static void GenerateThumbImage(string originalImagePath, string thumbImagePath, int newWidth, int newHeight) { Bitmap srcBmp = new Bitmap(originalImagePath); float ratio = 1; float minSize = Math.Min(newHeight, newHeight); if (srcBmp.Width > srcBmp.Height) { ratio = minSize / (float)srcBmp.Width; } else { ratio = minSize / (float)srcBmp.Height; } SizeF newSize = new SizeF(srcBmp.Width * ratio, srcBmp.Height * ratio); Bitmap target = new Bitmap((int)newSize.Width, (int)newSize.Height); using (Graphics graphics = Graphics.FromImage(target)) { graphics.CompositingQuality = CompositingQuality.HighSpeed; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.CompositingMode = CompositingMode.SourceCopy; graphics.DrawImage(srcBmp, 0, 0, newSize.Width, newSize.Height); using (MemoryStream memoryStream = new MemoryStream()) { target.Save(thumbImagePath); } } } } }