【问题标题】:C# : How to resize image proportionately with max heightC#:如何根据最大高度按比例调整图像大小
【发布时间】:2012-05-06 22:12:39
【问题描述】:

我需要在不改变纵横比的情况下按比例调整图像大小。我有代码可以用固定的高度和宽度调整大小,但我需要用最大高度(比如 600 像素)按比例调整图像大小。如何修改代码以满足我的要求?

public static void Main()
{
  var image = Image.FromFile(@"c:\logo.png");
  var newImage = ScaleImage(image, 300, 400);
  newImage.Save(@"c:\test.png", ImageFormat.Png);
}

public static Image ScaleImage(Image image, int maxWidth, int maxHeight)
 {
  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.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
  return newImage;
}

请提供您的宝贵意见。

【问题讨论】:

  • 这段代码有什么问题?
  • 恕我直言,请完成我的要求。此代码使用最大高度和最大宽度,而我需要按比例更改图像尺寸,将高度单独保持为最大数字(例如 600)。
  • 我不知道问题出在哪里,但如果我没记错的话,您的代码会在不改变纵横比的情况下调整图像大小。你能添加一个你期望发生的例子吗?
  • 使用 ratioY 代替 ratio,计算 newWidth 和 newHeigth
  • @remko:是的,你是绝对正确的,但在我的代码中,我将固定的高度和宽度传递给 ScaleImage 方法。我真正需要的是传递具有固定高度但宽度成比例的尺寸。有没有可能做到这一点?

标签: c# asp.net image-resizing aspect-ratio


【解决方案1】:

使用下面的函数

public Bitmap ProportionallyResizeBitmapByHeight(Bitmap imgToResize, int height)
{
  int sourceWidth = imgToResize.Width;
  int sourceHeight = imgToResize.Height;

  float scale = 0;

  scale = (height / (float)sourceHeight);

  int destWidth = (int)(sourceWidth * scale);
  int destHeight = (int)(sourceHeight * scale);

  Bitmap result = new Bitmap(destWidth, destHeight);
  result.SetResolution(imgToResize.HorizontalResolution, imgToResize.VerticalResolution);
  Graphics g = Graphics.FromImage(result);
  g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
  g.Dispose();

  return result;
}

【讨论】:

  • @Imran 非常感谢。让我试试看。
【解决方案2】:

这几乎感觉很容易,我觉得我错过了一些东西。无论如何,这不会奏效吗?

public static Image ScaleImage(Image image, int maxHeight) 
{ 
    var ratio = (double)maxHeight / 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; 
} 

【讨论】:

  • 非常感谢。让我试试看。
  • 我需要添加什么以防止缩放我适合最大高度或最大宽度的图像,并且它的一侧更大,只需减小尺寸直到它适合所需区域,同时保持份量。
【解决方案3】:

好吧,想一想整个过程: 如果您有一个 800 x 600 大小的图像并且想要将其调整为 newWidth x 400 高度(加上相应的 newWidth 将是什么),您可以通过将 newHeight(在您的情况下为 maxHeight)除以 600 并乘以 800 来获得比率这个比例对吧?

因此,在这种情况下,您需要将 maxWidth 和 maxHeight 更改为可选参数(例如 800 x 600),以赋予自己一些活力并获得以下信息:

public static Image ScaleImage(Image image, int maxWidth = 800, int maxHeight = 600)
 {

  int newWidth;
  int newHeight;
  double ratio = image.Height / image.Width;

  if(maxHeight != 600) {

     newWidth = image.Width * ratio;
     newHeight = maxHeight;

  }   

  Bitmap newImage = new Bitmap(newWidth, newHeight);
  Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
  return newImage;
}

我希望这会有所帮助。我没有测试它,但是我已经重写了我的VB代码,所以据说应该没问题...

这里还有一个 ResizeStream 方法:http://forums.asp.net/t/1576697.aspx/1,您可能会发现它很有用。 如果要保持图像质量,可以使用 CompositingQuality 和 SmoothingMode 等变量。

【讨论】:

  • 非常感谢。让我试试看。
  • 没问题。我希望它有所帮助。如果你撞到礁石,请告诉我。另一件事:这是基于最大高度的,因此您可能还需要检查 else if (maxWidth != 800) 并相应地更改 newWidth 和 newHeight。但无论如何,我包含的链接非常方便。
【解决方案4】:

100% 有效

   private static BitmapFrame CreateResizedImage(ImageSource source, int Max_width, int Max_height, int margin)
{
    float scaleHeight = (float)Max_width / (float)source.Height;
    float scaleWidth = (float)Max_height / (float)source.Width;
    float scale = Math.Min(scaleHeight, scaleWidth);

     int width = (int)(source.Width * scale);
     int height = (int)(source.Height * scale);


    var rect = new Rect(margin, margin, width - margin * 2, height - margin * 2);

    var group = new DrawingGroup();
    RenderOptions.SetBitmapScalingMode(group, BitmapScalingMode.HighQuality);
    group.Children.Add(new ImageDrawing(source, rect));

    var drawingVisual = new DrawingVisual();
    using (var drawingContext = drawingVisual.RenderOpen())
        drawingContext.DrawDrawing(group);

    var resizedImage = new RenderTargetBitmap(
        width, height,         // Resized dimensions
        96, 96,                // Default DPI values
        PixelFormats.Default); // Default pixel format
    resizedImage.Render(drawingVisual);

    return BitmapFrame.Create(resizedImage);
}


//--------Main------------//

  BitmapImage imageSource = (BitmapImage)ImagePreview.Source;
  var NewImage= CreateResizedImage(imageSource , 300, 300, 0);

【讨论】:

    猜你喜欢
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 2017-09-04
    • 2011-09-20
    • 2015-05-22
    • 2012-01-28
    相关资源
    最近更新 更多