views:

349

answers:

2

Hi all. I'm having some trouble resizing an image just by dragging the mouse. I found an average resize method and now am trying to modify it to use the mouse instead of given values.

The way I'm doing it makes sense to me but maybe you guys can give me some better ideas. I'm basically using the distance between the current location of the mouse and the previous location of the mouse as the scaling factor. If the distance between the current mouse location and the center of of the image is less than the distance between previous mouse location and the center of the image then the image gets smaller, and vice-versa.

With the code below I'm getting an Argument Exception (invalid parameter) when creating the new bitmap with the new height and width and I really don't understand why... any ideas?

---------------------------------EDIT------------------------------------------------------

Ok, thanks to Aaronaught the exception problem has been fixed and I updated the code below. Now I'm having a problem making the resize look smooth and finding a way to keep it from distorting to the point that you can't recognize the picture after resizing it multiple times.

My idea for keeping it from distorting is to change it back to the original image when it is within a certain range of sizes; but I'm not too sure how I would make that work without it looking wierd. Here's the updated code:

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;
    }
A: 

What happens if the mouse hasn't moved at all? You're not handling the case where nPercent evaluates to 0.

If you try to create a Bitmap with zero height and width, that is the exception you'll get.

Aaronaught
Thanks, didn't think about that. I fixed that and made limits on how big and small the picture can get so something like that can't happen again. But now I'm having trouble making the resizing look smooth and finding a way to fix the distortion after multiple resizings...
Gaax
@Gaax: Every resize should be done from the original image. As soon as you make a "copy of a copy", you start getting progressive degradation. You don't need complicated heuristics here, just always use the original as the source.
Aaronaught
I changed my code so I'm doing that now and its still doing the same thing but it just takes longer... Could it have something to do with the way I'm calculating the new height and width?
Gaax
@Gaxx: I strongly suspect that any progressive distortion you are still seeing is because you take the resulting image from this method and *replace* the original. I would need to see the rest of the code to know for sure.
Aaronaught
+1  A: 

To minimize distortion, you need to figure out the difference between the actual size of the image and the new size of the image and always create the re-sized image from the original image. Whenever the image size changes, call Refresh on the control that you are drawing the image on.

By the way, a PictureBox control with its SizeMode set to PictureBoxSizeMode.Zoom can handle the image resizing for you. Your code to re-size would only need to re-size the PictureBox. (Of course, it may not make sense to use a control in your situation, but I thought I would let you know just in case).

Zach Johnson