How to proportionally resize an image

When the width of height of an image object is changed, the image is scaled to fill the new size of the object.  If the changes to the width and height of an image are not in proportion this can lead to the image looking stretched and distorted.  In this lesson I will show how images can be resized proportionately so that they retain their original appearance, though smaller or larger.

Image resizing with the pointer tool

The pointer tool can be used to resize images proportionally.  When the pointer tool is in use and an object has been selected, resize handles (the small grey squares which indicate that an object is selected) appear at the corners and edges of the object.  By clicking and dragging on these handles, the object is resized by moving the edge or corner clicked on to adjust the width and/or height of the selected object.

If the Shift key is held down whilst moving the handle, then the proportions of the object will be preserved.  For example, if I hold Shift and drag the bottom edge upwards to reduce the size by half, then the right edge will automatically move to the left to reduce the width of the object by the same amount.

Resizing an image by script

An image will have been resized proportionately if the aspect ratio (the ratio between the width and height of the image) is preserved, that is if:

oldwidth / oldheight = newwidth / newheight

This can also be rewritten as:

oldwidth / newwidth = oldheight / newheight

So in order to preserve the aspect ratio when scaling an image, the width and height must both be scaled by the same factor.  When the height is doubled, so to must be the width.

Resize by scale factor

The following script command takes the long id of an image, and a scale factor, and applies it to the original width and height of the image:

``````command scaleImage pImageID, pScale
local tWidth, tHeight
put the formattedWidth of pImageID into tWidth
put the formattedHeight of pImageID into tHeight

put tWidth * pScale into tWidth
put tHeight * pScale into tHeight

lock screen
set the width of pImageID to tWidth
set the height of pImageID to tHeight
unlock screen
end scaleImage``````

Resize to set width or set height

You may wish to set a particular width or height on an image whilst maintaining the original proportions.  In such a case you can calculate the appropriate height or width by determining the ratio between the original and the desired width/height and applying that to both.

The following script command demonstrates this for a given width:

``````command setWidthProportional pImageID, pWidth
local tRatio, tHeight
put (the formattedWidth of pImageID) / pWidth into tRatio
put (the formattedHeight of pImageID) / tRatio into tHeight

lock screen
set the width of pImageID to pWidth
set the height of pImageID to tHeight
unlock screen
end setWidthProportional``````

Note that this command can be easily modified to accept a specified height, and calculate the appropriate width:

``````command setHeightProportional pImageID, pHeight
local tRatio, tWidth
put (the formattedHeight of pImageID) / pHeight into tRatio
put (the formattedWidth of pImageID) / tRatio into tWidth
lock screen
set the width of pImageID to tWidth
set the height of pImageID to pHeight
unlock screen
end setHeightProportional``````

Resize proportionately to fit within a given width and height

You may be creating an application where you wish to display an image within a limited area smaller than the image size.  In order to fit an image fully within a given area whilst still maintaining the original aspect ratio, unless the ratio of the image is the same as the new area, the image must either:

a) stretch across the full width of the area, but with a shorter height, or

b) stretch across the full height, but with a shorter width.

To determine which, we must calculate the proportional height given the new width, and also the proportional width given the new height.  If the calculated side of one of these new areas is greater than allowed then we use the other new area.

The following script command takes as parameters the long id of an image, a miximum width, and a maximum height and resizes the image proportionally to fit within:

``````command setAreaProportional pImageID, pWidth, pHeight
local tProportionalWidth, tProportionalHeight, tRatio
put (the formattedWidth of pImageID) / pWidth into tRatio
put (the formattedHeight of pImageID) / tRatio into tProportionalHeight
put (the formattedHeight of pImageID) / pHeight into tRatio
put (the formattedWidth of pImageID) / tRatio into tProportionalWidth
if tProportionalHeight > pHeight then
lock screen
set the width of pImageID to tProportionalWidth
set the height of pImageID to pHeight
unlock screen
else
lock screen
set the width of pImageID to pWidth
set the height of pImageID to tProportionalHeight
unlock screen
end if
end setAreaProportional``````

Look at this code, it works for me brutally.
--Code---
command ScaleImage pIdImg, pW,pH
put the formattedwidth of pIdImg into W
put the formattedheight of pIdImg into H

if H is 0 or W is 0 then
return error
pass ScaleImage
end if

switch
--Smaller
case W < pW and H < pW
set the width of pIdImg to W
set the height of pIdImg to H
break
default
put min(pH/H, pW/W) into R
set the height of pIdImg to H * R
set the width of pIdImg to W * R
end switch
end ScaleImage

Hassan

Why it is such a pain to adjust an image manually? You grab the handle and move but nothing seems to responds.

Elanor Buchanan

Hi Hassan, you should be able to resize an image using the handles as described in this lesson. Could you let us know what OS you are on and what version of LiveCode you are using so we can investigate?

Thank you.

Elanor

Carles B.

If pImageID is the ID that comes out in the inspector it does not work:

put (the formattedWidth of pImageID) / pWidth into tRatio
card id 1002: execution error at line 3 (Chunk: error in object expression) near "1007", char 9

If I change pImageID to (image foto), Yes

Regards,

Carles

Elanor Buchanan

Hi Carles

The lesson expects pImageID to be a long id, this would be something like

image id 1003 of card id 1002 of stack "TestStack"

To use the ID from the Property Inspector the correct syntax would be

put (the formattedWidth of image id pImageID) / pWidth into tRatio

I hope that helps.

Kind regards

Elanor

Simon Schvartzman

Why it takes so long to resize an image (in Android) by setting its width and height properties? Any suggestion to do it faster? Thanks

Elanor Buchanan

Hi Simon

What resizeQuality are your images set to? If you have them set to 'best' I would suggest trying 'good' or 'normal'. You could also use the prepare image command to preload the images into memory which could speed things up.

I hope that helps.

Elanor

Simon Schvartzman

Hi Elanor, thanks for you response. As a matter of fact I did not set the resizeQuality at all, so it was left at its "normal" default state.
Anyway after reseting the device everything works fine.
Best.

Tom Glod

Hey, these work really great, but any time you divide you have to round the result to 0 decimal places otherwise setting the height or width will fail.

Tom

To clarify my comment. An example......instead of

put (the formattedWidth of pImageID) / tRatio into tProportionalWidth

it should be

round(put (the formattedWidth of pImageID) / tRatio into tProportionalWidth)

so that

set the width of pImageID to tProportionalWidth

does not fail when there is a decimal point in the division.

Max Jacobi

Thank you very much for this lesson. It helped me a lot at coding my own image viewer. Works perfectly great.

trevix

Hello.
Suppose:
- The image content is bigger then the image control
- you change, over time, the content, different but always of the same size.

It is not clear to me when the resize of the image control should be done:
1) every time I change the content ?
2) once, after the first inserted content, and that will be good for any content change?
Thanks

Panos Merakos

Hello Trevix,

i think you should do it every time ou change the content, since setting the filename of an image uses the size of the image content, not the one of the image control.

Hope this helps,
Panos

Trevix

Even if the change of content is done with a Var?
put pValue into image "imageFromServer"

Panos Merakos

Hmm, I have not tested this TBH. I would suggest to do the resize every time you change the content to be on the safe side, but if for you it works by just changing it once (after the first inserted content), then feel free to go that way :)

Kind regards,
Panos