Resizing images - aspect ratio not maintained

Hi,

The following code is contained within a function, the requested zoom factor is simply an integer that we add on to make the image larger. Once this function is ran I create a new image based off the original image with the newImageWidth and newImageHeight, although my problem is that when zooming in the aspect ratio (shown by Debug.WriteLine) does not remain constant, which it obviously should; what can I do to help this?

Thanks,
Uni
///////////////////////////////////////////////////////////////////////////////////////////////////
//Prepare the variables.
///////////////////////////////////////////////////////////////////////////////////////////////////
int newImageWidth=0;
int newImageHeight=0;
 
 
///////////////////////////////////////////////////////////////////////////////////////////////////
//Calculate the aspect ratio of the frame and image from the width point of view and if the aspect
//ratio for the frame is higher then the picture will be height limited.
///////////////////////////////////////////////////////////////////////////////////////////////////
if(((float)Width/Height)>((float)img_OriginalImage.Width/img_OriginalImage.Height)){
	newImageWidth=(int)(Height*((float)img_OriginalImage.Width/img_OriginalImage.Height))+aRequestedZoomFactor;
	newImageHeight=Height+aRequestedZoomFactor;
	Debug.WriteLine(((float)newImageWidth/newImageHeight).ToString());
}
 
 
///////////////////////////////////////////////////////////////////////////////////////////////////
//Otherwise the aspect ratio of the frame must be lower than that of the aspect ratio of the
//picture. The aspect ratio we use for calculating the new width is from the point of the image
//height as opposed to the width.
///////////////////////////////////////////////////////////////////////////////////////////////////
else{
	newImageWidth=Width+aRequestedZoomFactor;
	newImageHeight=(int)(Width*((float)img_OriginalImage.Height/img_OriginalImage.Width))+aRequestedZoomFactor;
	Debug.WriteLine(((float)newImageWidth/newImageHeight).ToString());
}

Open in new window

LVL 3
Unimatrix_001Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cmorbachCommented:
Try to work with floating point precision, only. And only when you need the integer value (e.g. for the newly created bitmap) convert it to int.
0
Unimatrix_001Author Commented:
I'm not quite sure how else I can do it other than with floats? Could you give an example?

Thanks,
Uni
0
cmorbachCommented:
You could try to use floats only to store the sizes:

Not:
int newImageWidth=0;
int newImageHeight=0;
 
but
float ...

everywhere you store image sizes. Give it a try.
0
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

Unimatrix_001Author Commented:
Call me daft, but I'm struggling to see how that would help? Take the following two lines:

newImageWidth=(int)(Height*((float)img_OriginalImage.Width/img_OriginalImage.Height))+aRequestedZoomFactor;
newImageHeight=Height+aRequestedZoomFactor;

The only place where I could lose precision is (img_OriginalImage.Width/img_OriginalImage.Height), but that result never changes irrelevant of the requested zoom factor, so I'm unsure at which points in the application the precision is being lost?
0
Unimatrix_001Author Commented:
...or my method of calculating the aspect ratio is not correct...
0
Unimatrix_001Author Commented:
Actually, I have found a couple of mistakes in my calculation:


///////////////////////////////////////////////////////////////////////////////////////////////////
//Calculate the aspect ratio of the frame and image from the width point of view and if the aspect
//ratio for the frame is higher then the picture will be height limited.
///////////////////////////////////////////////////////////////////////////////////////////////////
if(((float)Width/Height)>((float)img_OriginalImage.Width/img_OriginalImage.Height)){
        newImageWidth=(int)(Height*((float)img_OriginalImage.Width/img_OriginalImage.Height))+aRequestedZoomFactor;
        newImageHeight=Height+aRequestedZoomFactor;
 
//The above line I use Height*((float)... this should be img_OriginalImage.Height.
        Debug.WriteLine(((float)newImageWidth/newImageHeight).ToString());
}
 
 
///////////////////////////////////////////////////////////////////////////////////////////////////
//Otherwise the aspect ratio of the frame must be lower than that of the aspect ratio of the
//picture. The aspect ratio we use for calculating the new width is from the point of the image
//height as opposed to the width.
///////////////////////////////////////////////////////////////////////////////////////////////////
else{
        newImageWidth=Width+aRequestedZoomFactor;
        newImageHeight=(int)(Width*((float)img_OriginalImage.Height/img_OriginalImage.Width))+aRequestedZoomFactor;
 
//The above line I use Width*((float)... this should be img_OriginalImage.Width.
       Debug.WriteLine(((float)newImageWidth/newImageHeight).ToString());
}

Open in new window

0
Unimatrix_001Author Commented:
Ack, sorry, corrections should be:

newImageHeight
newImageWidth

respectively.
0
Unimatrix_001Author Commented:
Btw, will be AFK for a couple of hours or so...
0
cmorbachCommented:
Well, I assumed your zooming algorithm was correct  ;)

I wrote this for you. You can give a zoom factor and the image is scaled. If it's larger then the draw surfaces, it's fitted to the drawable area - maintaining aspect ratio.

Note that the original aspect ratio and with of the image have to be initialized once and remembered!



Use the code below in a from with a label1 and a textbox1 containing the zoom factor in percent.
 public partial class Form1 : Form
    {
        float aspectRatio;
        float origWidth;
        float zoom;
 
        public Form1()
        {
            InitializeComponent();
 
            aspectRatio = (float)label1.Height / label1.Width;
            origWidth = (float)label1.Width;
            zoom = float.Parse(textBox1.Text) / 100.0f;
 
            label1.AutoSize = false;
            label1.BackColor = Color.Azure;
 
            Form1_Resize(null, null);
        }
 
        private void Form1_Resize(object sender, EventArgs e)
        {
            float maxWidth = (this.Width-label1.Left*2);    //centered draw surface (on form)
            float maxHeight = (this.Height-label1.Top*2);
 
 
            float newHeight;
            float newWidth;
 
            if (maxHeight / maxWidth > aspectRatio )
            {
                //height is larger, restrict in height
                newWidth = maxWidth;
                newHeight = maxWidth * aspectRatio;
            }
            else
            {
                //width is larger, restrict in width
                newHeight = maxHeight;
                newWidth = maxHeight / aspectRatio;
            }
 
            //maximal zoom
            if (newWidth > origWidth * zoom)
            {
                newWidth = origWidth * zoom;
                newHeight = newWidth * aspectRatio;
            }
 
            //set dimensions
            label1.Width = (int)newWidth;
            label1.Height = (int)newHeight;
        }
    }

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Unimatrix_001Author Commented:
Hi cmorbach,

Thank you! :) I'm back (obviously), so I'll take a look at your code.

Uni
0
Unimatrix_001Author Commented:
Hi there,

Thanks again for the code although I'm having great difficulty applying it to mine as I don't have anything like maxWidth or maxHeight?

Thanks again,
Uni
0
cmorbachCommented:
You shouldn't apply it but learn to understand it!  ;)

As I don't have your code (in context) I can't fix anything but just give hints...can't you provide a ( standalone) sample project?
0
Unimatrix_001Author Commented:
>>You shouldn't apply it but learn to understand it!  ;)
I fully agree, although I've been having difficulty understanding what they are even there for. Anyway, I've done a bit of rewriting and it seems that I've got it working, I'll accept one of your comments as after all you did provide a solution. :)

Thanks,
Uni
0
Unimatrix_001Author Commented:
Thank you. :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.