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

C# 在asp.net中调整图像大小而不丢失图像质量,c#,asp.net,image,image-scaling,C#,Asp.net,Image,Image Scaling,我正在开发一个ASP.NET 3.5 web应用程序,允许用户上传jpeg、gif、bmp或png图像。如果上传的图像尺寸大于103 x 32,我想将上传的图像调整为103 x 32。我读过一些博客帖子和文章,也尝试过一些代码示例,但似乎没有什么效果。有人成功地做到了这一点吗 通过创建图像的位图,然后调整位图的大小,我成功地做到了这一点……我不确定这是最好的还是最有效的方法,但它对我来说是有效的 在我的例子中,我需要将图像的高度和宽度减半 这就是我所做的 private Image get

我正在开发一个ASP.NET 3.5 web应用程序,允许用户上传jpeg、gif、bmp或png图像。如果上传的图像尺寸大于103 x 32,我想将上传的图像调整为103 x 32。我读过一些博客帖子和文章,也尝试过一些代码示例,但似乎没有什么效果。有人成功地做到了这一点吗

通过创建图像的位图,然后调整位图的大小,我成功地做到了这一点……我不确定这是最好的还是最有效的方法,但它对我来说是有效的

在我的例子中,我需要将图像的高度和宽度减半

这就是我所做的

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

不久前,我遇到了同样的问题,并以这种方式处理:

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);
}
private Image-RezizeImage(图像img、int-maxWidth、int-maxHeight)
{
if(img.Height

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

这是我使用的代码。它支持旋转,并将图像分辨率设置为的JPEG标准72dpi@24-位颜色(默认情况下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)
                   };
}
//
///调整图像大小并旋转图像,保持原始纵横比。不处理原件
///图像实例。
/// 
///图像实例
///期望宽度
///理想高度
///所需旋转唇型
///新的大小调整/旋转图像实例
公共静态图像大小调整(图像图像、整型宽度、整型高度、RotateLipType RotateLipType)
{
//克隆映像实例,因为我们不想调整原始映像实例的大小
var rotateImage=image.Clone()作为图像;
RotateImage.RotateFlap(RotateFlapType);
var newSize=计算尺寸(旋转图像、宽度、高度);
var resizedImage=新位图(newSize.Width、newSize.Height、PixelFormat.Format32bppArgb);
设置分辨率(72,72);
使用(var graphics=graphics.FromImage(resizedImage))
{
//设置参数以创建高质量的缩略图
graphics.InterpolationMode=InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode=SmoothingMode.AntiAlias;
graphics.CompositingQuality=CompositingQuality.HighQuality;
graphics.PixelOffsetMode=PixelOffsetMode.HighQuality;
//使用图像属性,以便在调整大小后删除图像周围的黑色/灰色边框
//(最明显的是白色图像),更多信息请参见本文:
// http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
使用(var attribute=newimageattributes())
{
SetWrapMode(WrapMode.TileFlipXY);
//将调整大小的图像绘制到位图
graphics.DrawImage(RotateImage,新矩形(新点(0,0),newSize),0,0,RotateImage.Width,RotateImage.Height,GraphicsUnit.Pixel,属性);
}
}
返回resizedImage;
}
/// 
///计算图像的大小调整尺寸,保留纵横比。
/// 
///图像实例
///期望宽度
///理想高度
///使用调整大小的尺寸标注调整实例的大小
私有静态大小CalculateResizedDimensions(图像图像、int-desiredWidth、int-desiredHeight)
{
var widthScale=(双精度)desiredWidth/image.Width;
var heightScale=(双精度)desiredHeight/image.Height;
//缩放到较小的比例,这适用于放大和缩小
变量刻度=宽度刻度<高度刻度?宽度刻度:高度刻度;
返回新尺寸
{
宽度=(int)(比例*图像宽度),
高度=(整数)(比例*图像高度)
};
}

与位图实际大小调整相关的代码如下所示

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;
}
}
这篇博文包含图像大小调整和压缩(如果需要)的完整源代码


发布您正在使用的无效代码,并解释它以何种方式无效。是否强制103x32?或者最适合?
ImageBuilder.Current.Build(HttpPostedFile文件,字符串路径,新的大小设置(“宽度=103,高度=32”)//在新版本中使用时,我还考虑到我不会拉伸图像,但这应该很容易解决:-P(提示:
ration=Math.Min(ration,1.0);
)嗯,有一个,比如像素偏移。谢谢。不幸的是,当我将一个大的(3264x2448)图像缩小到60x45时,我从中看到的结果是顶部和左侧边缘模糊。这是一个很好的解决方案。请注意,在运行PropertyInfo之后,它是空的。因此,如果您打算将图像旋转为竖直,请先这样做。感谢您指向
public static System.Drawing.Image ScaleImage(System.Drawing.Image image, int maxImageHeight)
    {
        /* we will resize image based on the height/width ratio by passing expected height as parameter. Based on Expected height and current image height, new ratio will be arrived and using the same we will do the resizing of image width. */

        var ratio = (double)maxImageHeight / image.Height;
        var newWidth = (int)(image.Width * ratio);
        var newHeight = (int)(image.Height * ratio);
        var newImage = new Bitmap(newWidth, newHeight);
        using (var g = Graphics.FromImage(newImage))
        {
            g.DrawImage(image, 0, 0, newWidth, newHeight);
        }
        return newImage;
    }
  decimal size = Math.Round(((decimal)fUpload.PostedFile.ContentLength / (decimal)1024), 2);
        DirectoryInfo dir = new DirectoryInfo(MapPath("Images"));
        FileInfo[] files = dir.GetFiles();
         foreach (FileInfo info in files)
        {
              decimal size2 = Math.Round(((decimal)info.Length / (decimal)1024), 2);
              string Image_name = info.Name.ToString();
              string targetPath = Server.MapPath("Images/" + Image_name);
              string strm = Server.MapPath("Images/" + Image_name);
              var targetFile = targetPath;
              ReduceImageSize(0.5, strm, targetFile, Image_name);
         }
   // Fixed Size Image Generate Code
 protected void btnUpload_Click(object sender, EventArgs e)
    {

 decimal size = Math.Round(((decimal)fUpload.PostedFile.ContentLength / (decimal)1024), 2);
        DirectoryInfo dir = new DirectoryInfo(MapPath("Images"));
        FileInfo[] files = dir.GetFiles();
         foreach (FileInfo info in files)
        {
              decimal size2 = Math.Round(((decimal)info.Length / (decimal)1024), 2);
              string Image_name = info.Name.ToString();
              string targetPath = Server.MapPath("Images/" + Image_name);
              string strm = Server.MapPath("Images/" + Image_name);
              var targetFile = targetPath;
              ReduceImageSize(0.5, strm, targetFile, Image_name);
         }
}

 public void ReduceImageSize(double scaleFactor, String sourcePath, string targetPath, string Image_name)
    {

 // Fixed Size Image Generate Code

       public void ReduceImageSize(double scaleFactor, String sourcePath, string targetPath, string Image_name)
    {
        using (var image = System.Drawing.Image.FromFile(sourcePath))
               {

            //var newWidth = (int)(image.Width  * scaleFactor);
            //var newHeight = (int)(image.Height * scaleFactor);
            var newWidth = (int)(500 * scaleFactor);
            var newHeight = (int)(500 * scaleFactor);
            var thumbnailImg = new Bitmap(newWidth, newHeight);
            var thumbGraph = Graphics.FromImage(thumbnailImg);
            thumbGraph.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
            thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
            var imageRectangle = new System.Drawing.RectangleF (0, 0, newWidth, newHeight);
            thumbGraph.DrawImage(image, imageRectangle);


            MemoryStream s = new MemoryStream();
            thumbnailImg.Save(s, System.Drawing.Imaging.ImageFormat.Png);
            s.Position = 0;
            byte[] image2 = new byte[525000];// 512kb =525000  
            s.Read(image2, 0, image2.Length);

            Guid guid = Guid.NewGuid();
            string Server_MapPath = Server.MapPath("~/Image Compress/" + Image_name + guid.ToString() + ".PNG");//Your Compressor Image Save Path

            System.IO.FileStream fs = new System.IO.FileStream(Server_MapPath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite);
            fs.Write(image2, 0, image2.Length);

        }
    }