2014-07-25 111 views
1

我正在使用以下系统绘图代码来调整上传图片的大小。问题在于,横向或纵向图像变形导致系统绘图使它们变成方形。是否可以只调整宽度并保持高度成比例?如何?由于调整上传宽度并保持高度比例成正比

HttpPostedFile imageFile = UploadImages.PostedFile; 
          System.Drawing.Image ri = System.Drawing.Image.FromStream(imageFile.InputStream); 
          ri = ResizeBitmap((Bitmap) ri, 200, 200); 

private Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight) 
    { 
     Bitmap result = new Bitmap(nWidth, nHeight); 
     using (Graphics g = Graphics.FromImage((System.Drawing.Image)result)) 
      g.DrawImage(b, 0, 0, nWidth, nHeight); 
     return result; 
    } 
+0

你的意思是你想要一个200x高的图像,如果纵向和宽度X 200如果纵向? – dbc

+0

否..... 200像素高度如果纵向和200像素宽度如果横向 – Gloria

+0

啊右 - 在快速打字时感到困惑。我只是在几张图片上测试了这一点,当我打开它们并将它们保存在本地计算机上时,它工作正常。如果您的图片在上传到服务器后似乎损坏,那么问题可能出在上传上? – dbc

回答

1

如果你想什么如果要创建一个200像素宽的新位图,并且高度按比例缩放,则可以这样做:

private static int CalculateProportionalHeight(int oldWidth, int oldHeight, int newWidth) 
    { 
     if (oldWidth <= 0 || oldHeight <= 0 || newWidth <= 0) 
      // For safety. 
      return oldHeight; 
     double widthFactor = (double)newWidth/(double)oldWidth; 
     int newHeight = (int)Math.Round(widthFactor * (double)oldHeight); 
     if (newHeight < 1) 
      newHeight = 1; // just in case. 
     return newHeight; 
    } 

    private static Bitmap ResizeBitmap(Bitmap b, int nWidth) 
    { 
     int nHeight = CalculateProportionalHeight(b.Width, b.Height, nWidth); 
     Bitmap result = new Bitmap(nWidth, nHeight); 
     using (Graphics g = Graphics.FromImage((System.Drawing.Image)result)) 
      g.DrawImage(b, 0, 0, nWidth, nHeight); 
     return result; 
    } 

或者您是否希望创建一个200x200位图,并将旧图像缩放以适合内部,如果需要,还可以使用letterboxed

更新

如果您正在寻找创建一个固定的200×200大小的图像,在图像缩小比例,以适应和信箱,这应该这样做:

static RectangleF PlaceInside(int oldWidth, int oldHeight, int newWidth, int newHeight) 
    { 
     if (oldWidth <= 0 || oldHeight <= 0 || newWidth <= 0 || newHeight <= 0) 
      return new RectangleF(oldWidth, oldHeight, newWidth, newHeight); 
     float widthFactor = (float)newWidth/(float)oldWidth; 
     float heightFactor = (float)newHeight/(float)oldHeight; 
     if (widthFactor < heightFactor) 
     { 
      // prefer width 
      float scaledHeight = widthFactor * oldHeight; 
      // new new RectangleF(x, y, width, height) 
      return new RectangleF(0, (newHeight - scaledHeight)/2.0f, newWidth, scaledHeight); 
     } 
     else 
     { 
      // prefer height 
      float scaledWidth = heightFactor * oldWidth; 
      // new new RectangleF(x, y, width, height) 
      return new RectangleF((newWidth - scaledWidth)/2.0f, 0, scaledWidth, newHeight); 
     } 
    } 

    private static Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight) 
    { 
     int oldWidth = b.Width; 
     int oldHeight = b.Height; 
     Bitmap result = new Bitmap(nWidth, nHeight); 
     using (Graphics g = Graphics.FromImage((System.Drawing.Image)result)) 
     { 
      var box = PlaceInside(oldWidth, oldHeight, nWidth, nHeight); 
      g.DrawImage(b, box); 
     } 
     return result; 
    } 

更新2

这里是一个版本,它创建宽度200和比例高度的图像,如果风景和高度200和比例宽度如果po rtrait:

private static Bitmap ResizeBitmapUpto(Bitmap b, int nWidth, int nHeight, System.Drawing.Drawing2D.InterpolationMode interpolationMode) 
    { 
     int oldWidth = b.Width; 
     int oldHeight = b.Height; 
     var box = PlaceInside(oldWidth, oldHeight, nWidth, nHeight); 
     int actualNewWidth = (int)Math.Max(Math.Round(box.Width), 1); 
     int actualNewHeight = (int)Math.Max(Math.Round(box.Height), 1); 
     Bitmap result = new Bitmap(actualNewWidth, actualNewHeight); 
     using (Graphics g = Graphics.FromImage((System.Drawing.Image)result)) 
     { 
      g.InterpolationMode = interpolationMode; 
      g.DrawImage(b, 0, 0, actualNewWidth, actualNewHeight); 
     } 
     return result; 
    } 

我增加了一个interpolationMode这样你就可以用不同的特质按照Ksv3n的答案实验。

(希望)最后更新

下面是测试设置我用来验证码。我可以在计算机上成功打开,调整大小和保存各种图像。

public static void TestResizeBitmapUpto(string file, string newFile) 
    { 
     try 
     { 
      using (var image = Bitmap.FromFile(file)) 
      { 
       if (image == null) 
        return; 
       using (Bitmap b = new Bitmap(image)) 
       { 
        using (var newBitmap = ResizeBitmapUpto(b, 200, 200, System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor)) 
        { 
         newBitmap.Save(newFile); 
        } 
       } 
      } 
     } 
     catch (System.IO.FileNotFoundException e) 
     { 
      Debug.WriteLine(e.ToString()); 
     } 
     catch (Exception e) 
     { 
      Debug.WriteLine(e.ToString()); 
     } 
    } 
1

缺少了什么在你的代码是:

g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; 

这里是你可以用与keeeping它的比例来调整图像的方法:

private Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight) 
    { 
     Bitmap result = new Bitmap(nWidth, nHeight); 
     using (Graphics g = Graphics.FromImage((System.Drawing.Image)result)) 
     { 
      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; 
      g.DrawImage(b, 0, 0, nWidth, nHeight); 
     } 
     return result; 
    } 
+1

+1正确,但我认为他也缺少基于原始vs理想宽度分数的高度分量的计算。 –

+0

此代码中的height参数会发生什么ri = ResizeBitmap((Bitmap)ri,200,200); – Gloria

0

g.DrawImage将图像拉伸到你定义的内容(在你的情况200/200是一个正方形)。

你需要计算nWidth和nHeight参数实际值:

// original image (b.Width, b.Height) 
double originalWidth = 200; 
double originalHeight = 100; 

// user defined wanted width 
double wantedWidth = 200; // nWidth parameter to your method 
double wantedHeight = 300; // nHeight parameter to your method 

double ratioW = originalWidth/wantedWidth; 
double ratioH = originalHeight/wantedHeight; 

double ratio = Math.Max(ratioW, ratioH); 

// rectangle proportional to the original that fits into the wanted 
double destinationWidth = originalWidth/ratio; // what you pass to DrawImage as nWidth 
double destinationHeight = originalHeight/ratio; // what you pass to DrawImage as nWidth 

它的作用是计算出原始的宽度和高度的比例,并希望图像,并采取它的最大值。使用它来分割原始值,这将使它们完全适合想要的矩形。

这将绘制缩放的图像对齐的顶部或左侧取决于什么是方向,因为生成的图像将等于或大于想要的或原始的。为了使它在生成的图像中居中,您需要调整DrawImage()的左侧和顶部坐标,方法是将宽度/高度的差值除以2并除以2。

如果由此产生的图像可以是不同的大小,那么用户指定的(nWidth/nHeight),那么你可以简单地使用destinationWidth/Height初始化它,然后返回它,而不用担心居中。

相关问题