3

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

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

        }
    }
4

2 回答 2

1

在我看来(来自 scaleAvg 计算)就像您正在重新缩放已经缩放的图像。这是一个非常糟糕的主意,因为缩放是有损的,并且错误会累积。相反,保留清晰的原始图像的副本并将原始图像直接缩放到当前大小。

另外,我建议使用不同的范数,也许是曼哈顿距离,而不是当前的笛卡尔距离,这是一个二范数。

如果您确实继续使用二范数,请考虑摆脱 Math.Pow 调用。它们可能只是整体缩放复杂性的一小部分,这无关紧要,但乘以本身应该比 Math.Pow 对一个数字求平方要快得多。

于 2010-04-02T05:20:00.043 回答
1

如果您使用图像的中心,您的缩放将不会平滑。相反,使用初始鼠标向下点(称为 p0)。此外,不要使用从该点到当前拖动点 (e) 的距离,而是沿一个轴取差值(例如 exp(eY - p0.Y))。

于 2010-04-02T05:29:54.263 回答