2010-03-21 53 views
1

我在通过拖动鼠标调整图像大小时遇到​​了一些问题。我找到了一个平均调整大小的方法,现在正在尝试修改它以使用鼠标而不是给定的值。使用鼠标拖动调整图像大小(C#)

我这样做的方式对我有意义,但也许你们可以给我一些更好的想法。我基本上使用鼠标的当前位置和鼠标的前一个位置之间的距离作为缩放因子。如果当前鼠标位置与图像中心之间的距离小于之前鼠标位置与图像中心之间的距离,则图像变小,反之亦然。

随着下面的代码,我创建新的位图与新的高度和宽度时,我得到一个参数异常(无效参数),我真的不明白为什么......任何想法?

---------------------------------编辑------------ ------------------------------------------

好的,多亏了Aaronaught异常问题已得到解决,我更新了下面的代码。现在我遇到了一个问题,使调整大小看起来顺畅,并找到一种方法来防止它扭曲,以至于在多次调整大小后无法识别图片。

我的想法是让它在一定的尺寸范围内变回原始图像;但我不太确定如何在没有看起来奇怪的情况下完成这项工作。以下是更新的代码:

private static Image resizeImage(Image imgToResize, System.Drawing.Point prevMouseLoc, System.Drawing.Point currentMouseLoc) 
    { 
     int sourceWidth = imgToResize.Width; 
     int sourceHeight = imgToResize.Height; 
     float dCurrCent = 0; 
     float dPrevCent = 0; 
     float dCurrPrev = 0; 
     bool increase = true; 
     System.Drawing.Point imgCenter = new System.Drawing.Point(); 
     float nPercent = 0; 

     imgCenter.X = imgToResize.Width/2; 
     imgCenter.Y = imgToResize.Height/2; 

     // Calculating the distance between the current mouse location and the center of the image 
     dCurrCent = (float)Math.Sqrt(Math.Pow(currentMouseLoc.X - imgCenter.X, 2) + Math.Pow(currentMouseLoc.Y - imgCenter.Y, 2)); 

     // Calculating the distance between the previous mouse location and the center of the image 
     dPrevCent = (float)Math.Sqrt(Math.Pow(prevMouseLoc.X - imgCenter.X, 2) + Math.Pow(prevMouseLoc.Y - imgCenter.Y, 2)); 

     // Setting flag to increase or decrease size 
     if (dCurrCent >= dPrevCent) 
     { 
      increase = true; 
     } 
     else 
     { 
      increase = false; 
     } 

     // Calculating the scaling factor 
     dCurrPrev = nPercent = (float)Math.Sqrt(Math.Pow(currentMouseLoc.X - prevMouseLoc.X, 2) + Math.Pow(currentMouseLoc.Y - prevMouseLoc.Y, 2)); 

     if (increase) 
     { 
      nPercent = (float)dCurrPrev; 
     } 
     else 
     { 
      nPercent = (float)(1/dCurrPrev); 
     } 

     // Calculating the new height and width of the image 
     int destWidth = (int)(sourceWidth * nPercent); 
     int destHeight = (int)(sourceHeight * nPercent); 

     // Create new bitmap, resize image (within limites) and return it 
     if (nPercent != 0 && destWidth > 100 && destWidth < 600) 
     { 
      Bitmap b = new Bitmap(destWidth, destHeight); 
      Graphics g = Graphics.FromImage((Image)b); 
      g.InterpolationMode = InterpolationMode.HighQualityBicubic; 

      g.DrawImage(imgToResize, 0, 0, destWidth, destHeight); 
      g.Dispose(); 

      return (Image)b; 
     } 
     else 
      return imgToResize; 
    } 

回答

0

如果鼠标根本没有移动,会发生什么?您无法处理nPercent评估为0的情况。

如果您尝试创建零高度和宽度为零的Bitmap,那么您将会得到例外。

+0

谢谢,没有想到这一点。我解决了这个问题,并且限制了图片可以获得的大小,所以类似的东西不会再发生。但现在我无法使调整大小的外观变得平滑,并找到一种方法来修复多次重新调整后的失真... – Gaax

+1

@Gaax:每个调整大小都应该从原始图像完成。只要你做了一份“副本”,你就开始逐渐退化。这里不需要复杂的启发式,只是始终使用原始数据源。 – Aaronaught

+0

我改变了我的代码,所以我现在这样做,它仍然在做同样的事情,但它只需要更长的时间......这可能与我计算新的高度和宽度的方式有关吗? – Gaax

1

为了使失真最小化,您需要计算出图像的实际尺寸与图像的新尺寸之间的差异,并始终从原始图像中创建重新尺寸的图像。每当图像大小发生变化时,请在要绘制图像的控件上调用Refresh

顺便说一下,PictureBox控件的SizeMode设置为PictureBoxSizeMode.Zoom可以处理您的图片大小调整。您重新调整大小的代码只需要重新调整PictureBox的大小。 (当然,在你的情况下使用控件可能没有意义,但我想我会让你知道以防万一)。

相关问题