2010-04-02 45 views
3

我正在尝试使用鼠标的位置来计算缩放图像的缩放因子。基本上,你越远离图像中心,它越大;而越接近你得到的中心,它越小。到目前为止我有一些代码,但它的行为真的很奇怪,我完全没有更多的想法。首先我会告诉你,我试图做的一件事是平均5距离以获得更平滑的调整大小的动画。这是我的代码:在WinForms应用程序中使用鼠标缩放图像?

private void pictureBoxScale_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (rotateScaleMode && isDraggingToScale) 
    { 
     // For Scaling    
     int sourceWidth = pictureBox1.Image.Width; 
     int sourceHeight = pictureBox1.Image.Height; 
     float dCurrCent = 0; // distance between the current mouse pos and the center of the image 
     float dPrevCent = 0; // distance between the previous mouse pos and the center of the image 

     System.Drawing.Point imgCenter = new System.Drawing.Point(); 

     imgCenter.X = pictureBox1.Location.X + (sourceWidth/2); 
     imgCenter.Y = pictureBox1.Location.Y + (sourceHeight/2); 

     // Calculating the distance between the current mouse location and the center of the image 
     dCurrCent = (float)Math.Sqrt(Math.Pow(e.X - imgCenter.X, 2) + Math.Pow(e.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)); 

     if (smoothScaleCount < 5) 
     { 
      dCurrCentSmooth[smoothScaleCount] = dCurrCent; 
      dPrevCentSmooth[smoothScaleCount] = dPrevCent; 
     } 


     if (smoothScaleCount == 4) 
     { 
      float currCentSum = 0; 
      float prevCentSum = 0; 
      for (int i = 0; i < 4; i++) 
      { 
       currCentSum += dCurrCentSmooth[i]; 
      } 
      for (int i = 0; i < 4; i++) 
      { 
       prevCentSum += dPrevCentSmooth[i]; 
      } 

      float scaleAvg = (currCentSum/5)/(prevCentSum/5); 


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

      // If statement is for limiting the size of the image 
      if (destWidth > (currentRotatedImage.Width/2) && destWidth < (currentRotatedImage.Width * 3) && destHeight > (currentRotatedImage.Height/2) && destWidth < (currentRotatedImage.Width * 3)) 
      { 
       AForge.Imaging.Filters.ResizeBilinear resizeFilter = new AForge.Imaging.Filters.ResizeBilinear(destWidth, destHeight); 
       pictureBox1.Image = resizeFilter.Apply((Bitmap)currentRotatedImage); 
       pictureBox1.Size = pictureBox1.Image.Size; 
       pictureBox1.Refresh(); 
      } 

      smoothScaleCount = -1; 
     } 
     prevMouseLoc = e.Location; 
     currentScaledImage = pictureBox1.Image; 
     smoothScaleCount++; 

    } 
} 

编辑:感谢Ben Voigt和Ray现在一切正常。唯一错误的是,用我做这件事的方式,图像不能保持它的比例;但我会在稍后解决。下面是我对那些想知道谁:

private void pictureBoxScale_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (rotateScaleMode && isDraggingToScale) 
     { 
      // For Scaling    
      int sourceWidth = pictureBox1.Image.Width; 
      int sourceHeight = pictureBox1.Image.Height; 
      int scale = e.X + p0.X; //p0 is the location of the mouse when the button first came down 
      int destWidth = (int)(sourceWidth + (scale/10)); //I divide it by 10 to make it slower 
      int destHeight = (int)(sourceHeight + (scale/10)); 

      if (destWidth > 20 && destWidth < 1000 && destHeight > 20 && destWidth < 1000) 
      { 
       AForge.Imaging.Filters.ResizeBilinear resizeFilter = new AForge.Imaging.Filters.ResizeBilinear(destWidth, destHeight); 
       pictureBox1.Image = resizeFilter.Apply((Bitmap)currentRotatedImage); 
       pictureBox1.Size = pictureBox1.Image.Size; 
       pictureBox1.Refresh(); 
      } 
      currentScaledImage = pictureBox1.Image; // This is only so I can rotate the scaled image in another part of my program 

     } 
    } 
+1

那么你的问题是什么? – Aaronaught 2010-04-02 04:07:06

+0

@Aaronaught:“为什么这表现很奇怪?” – 2010-04-02 04:11:02

+1

我会建议使用调试器进行单元测试和/或单步调试。我也会尝试没有“平滑缩放”,因为有些部分看起来很可疑。 – 2010-04-02 04:12:59

回答

1

如果使用图像的中心,则缩放比例将不平滑。相反,使用最初的鼠标点(称为p0)。而且,不是使用从该点到当前拖动点(e)的距离,而是沿着一个轴取差值(例如,exp(e.Y - p0.Y))。

+0

我不确定你为什么建议用exp来计算infinity-norm。你的意思是最大(abs(x1-x2),abs(y1-y2))? – 2010-04-02 15:12:08

+0

对我有意义,我喜欢。 – Gaax 2010-04-02 19:58:04

+0

@Ben。你不想要一个规范。你需要+/-值。 exp只是从+/-值中获得缩放值的一些方法。 – Ray 2010-04-02 20:40:01

1

在我看来(从scaleAvg计算)就像你重新缩放已缩放后的图像。这是一个非常糟糕的想法,因为缩放是有损的,而且错误会累积起来。相反,请保留一份清晰的原始图像,并将原稿直接缩放至当前尺寸。另外,我建议使用不同的标准,也许是曼哈顿距离,而不是当前的笛卡尔距离,这是一个两个标准。

如果您确实继续使用双标准,请考虑删除Math.Pow调用。它们可能只是整体比例复杂度的一小部分,它并不重要,但乘以其自身的速度应比Math.Pow快于数字的平方。

相关问题