Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Resizing images - aspect ratio not maintained

Posted on 2009-07-08
14
Medium Priority
?
354 Views
Last Modified: 2012-05-07
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

0
Comment
Question by:Unimatrix_001
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 4
14 Comments
 
LVL 3

Expert Comment

by:cmorbach
ID: 24805781
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
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24805924
I'm not quite sure how else I can do it other than with floats? Could you give an example?

Thanks,
Uni
0
 
LVL 3

Expert Comment

by:cmorbach
ID: 24805959
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24805991
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
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24806037
...or my method of calculating the aspect ratio is not correct...
0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24806080
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
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24806096
Ack, sorry, corrections should be:

newImageHeight
newImageWidth

respectively.
0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24806134
Btw, will be AFK for a couple of hours or so...
0
 
LVL 3

Accepted Solution

by:
cmorbach earned 2000 total points
ID: 24806831
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
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24807767
Hi cmorbach,

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

Uni
0
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24808323
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
 
LVL 3

Expert Comment

by:cmorbach
ID: 24808496
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
 
LVL 3

Author Comment

by:Unimatrix_001
ID: 24808605
>>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
 
LVL 3

Author Closing Comment

by:Unimatrix_001
ID: 31601203
Thank you. :)
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article series is supposed to shed some light on the use of IDisposable and objects that inherit from it. In essence, a more apt title for this article would be: using (IDisposable) {}. I’m just not sure how many people would ge…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question