在asp.net中调整图像大小而不会丢失图像质量

我正在开发一个ASP.NET 3.5 Web应用程序,允许我的用户上传jpeg,gif,bmp或png图像。 如果上传的图片尺寸大于103 x 32,我想将上传的图片大小调整为103 x 32。我已经阅读了一些博客文章和文章,也尝试了一些代码示例,但是没有任何一个可以正常工作。 有没有人成功做到这一点?

我曾经遇到过同样的问题,并以这种方式处理:

 private Image RezizeImage(Image img, int maxWidth, int maxHeight) { if(img.Height < maxHeight && img.Width < maxWidth) return img; using (img) { Double xRatio = (double)img.Width / maxWidth; Double yRatio = (double)img.Height / maxHeight; Double ratio = Math.Max(xRatio, yRatio); int nnx = (int)Math.Floor(img.Width / ratio); int nny = (int)Math.Floor(img.Height / ratio); Bitmap cpy = new Bitmap(nnx, nny, PixelFormat.Format32bppArgb); using (Graphics gr = Graphics.FromImage(cpy)) { gr.Clear(Color.Transparent); // This is said to give best quality when resizing images gr.InterpolationMode = InterpolationMode.HighQualityBicubic; gr.DrawImage(img, new Rectangle(0, 0, nnx, nny), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel); } return cpy; } } private MemoryStream BytearrayToStream(byte[] arr) { return new MemoryStream(arr, 0, arr.Length); } private void HandleImageUpload(byte[] binaryImage) { Image img = RezizeImage(Image.FromStream(BytearrayToStream(binaryImage)), 103, 32); img.Save("IMAGELOCATION.png", System.Drawing.Imaging.ImageFormat.Gif); } 

我刚刚读到,这是获得最高质量的方式。

这是我使用的代码。 它支持旋转,并将图像分辨率设置为72dpi @ 24位色彩的JPEG标准(默认情况下,GDI +以96dpi @ 32位色彩保存图像)。 它还修复了某些人在调整图像大小时遇到​​的黑色/灰色边框问题。

 /// <summary> /// Resizes and rotates an image, keeping the original aspect ratio. Does not dispose the original /// Image instance. /// </summary> /// <param name="image">Image instance</param> /// <param name="width">desired width</param> /// <param name="height">desired height</param> /// <param name="rotateFlipType">desired RotateFlipType</param> /// <returns>new resized/rotated Image instance</returns> public static Image Resize(Image image, int width, int height, RotateFlipType rotateFlipType) { // clone the Image instance, since we don't want to resize the original Image instance var rotatedImage = image.Clone() as Image; rotatedImage.RotateFlip(rotateFlipType); var newSize = CalculateResizedDimensions(rotatedImage, width, height); var resizedImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format32bppArgb); resizedImage.SetResolution(72, 72); using (var graphics = Graphics.FromImage(resizedImage)) { // set parameters to create a high-quality thumbnail graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.SmoothingMode = SmoothingMode.AntiAlias; graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; // use an image attribute in order to remove the black/gray border around image after resize // (most obvious on white images), see this post for more information: // http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx using (var attribute = new ImageAttributes()) { attribute.SetWrapMode(WrapMode.TileFlipXY); // draws the resized image to the bitmap graphics.DrawImage(rotatedImage, new Rectangle(new Point(0, 0), newSize), 0, 0, rotatedImage.Width, rotatedImage.Height, GraphicsUnit.Pixel, attribute); } } return resizedImage; } /// <summary> /// Calculates resized dimensions for an image, preserving the aspect ratio. /// </summary> /// <param name="image">Image instance</param> /// <param name="desiredWidth">desired width</param> /// <param name="desiredHeight">desired height</param> /// <returns>Size instance with the resized dimensions</returns> private static Size CalculateResizedDimensions(Image image, int desiredWidth, int desiredHeight) { var widthScale = (double)desiredWidth / image.Width; var heightScale = (double)desiredHeight / image.Height; // scale to whichever ratio is smaller, this works for both scaling up and scaling down var scale = widthScale < heightScale ? widthScale : heightScale; return new Size { Width = (int) (scale * image.Width), Height = (int) (scale * image.Height) }; } 

与实际调整位图关联的代码如下所示。

 public static Bitmap ResizeBitmap( Bitmap originalBitmap, int requiredHeight, int requiredWidth ) { int[] heightWidthRequiredDimensions; // Pass dimensions to worker method depending on image type required heightWidthRequiredDimensions = WorkDimensions(originalBitmap.Height, originalBitmap.Width, requiredHeight, requiredWidth); Bitmap resizedBitmap = new Bitmap( heightWidthRequiredDimensions[1], heightWidthRequiredDimensions[0] ); const float resolution = 72; resizedBitmap.SetResolution( resolution, resolution ); Graphics graphic = Graphics.FromImage( (Image) resizedBitmap ); graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; graphic.DrawImage( originalBitmap, 0, 0, resizedBitmap.Width, resizedBitmap.Height ); graphic.Dispose(); originalBitmap.Dispose(); //resizedBitmap.Dispose(); // Still in use return resizedBitmap; } private static int[] WorkDimensions(int originalHeight, int originalWidth, int requiredHeight, int requiredWidth ) { int imgHeight = 0; int imgWidth = 0; imgWidth = requiredHeight; imgHeight = requiredWidth; int requiredHeightLocal = originalHeight; int requiredWidthLocal = originalWidth; double ratio = 0; // Check height first // If original height exceeds maximum, get new height and work ratio. if ( originalHeight > imgHeight ) { ratio = double.Parse( ( (double) imgHeight / (double) originalHeight ).ToString() ); requiredHeightLocal = imgHeight; requiredWidthLocal = (int) ( (decimal) originalWidth * (decimal) ratio ); } // Check width second. It will most likely have been sized down enough // in the previous if statement. If not, change both dimensions here by width. // If new width exceeds maximum, get new width and height ratio. if ( requiredWidthLocal >= imgWidth ) { ratio = double.Parse( ( (double) imgWidth / (double) originalWidth ).ToString() ); requiredWidthLocal = imgWidth; requiredHeightLocal = (int) ( (double) originalHeight * (double) ratio ); } int[] heightWidthDimensionArr = { requiredHeightLocal, requiredWidthLocal }; return heightWidthDimensionArr; } } 

这个博客文章包含图像大小调整和压缩(如果需要)的完整源代码,

http://blog.bombdefused.com/2010/08/bulk-image-optimizer-in-c-full-source.html

我已经成功通过创build图像的位图,然后调整位图的大小来做到这一点…我不确定这是否是最好的或最有效的方式做到这一点,但它适用于我。

就我而言,我需要将图像的高度和宽度减半。

这是我做的。

  private Image getImageFromBytes(byte[] myByteArray) { System.IO.MemoryStream newImageStream = new System.IO.MemoryStream(myByteArray, 0, myByteArray.Length); Image image = Image.FromStream(newImageStream, true); Bitmap resized = new Bitmap(image, image.Width / 2, image.Height / 2); image.Dispose(); newImageStream.Dispose(); return resized; }