Scaling an Image to a Rect

Alex Tweedly alex at tweedly.net
Wed Oct 16 00:19:26 CEST 2013


Dan,

What you're doing now will work most times, but not always, because it 
calculates the ratio to use based on which dimension is larger, rather 
than on which ratio is the larger. If you had an image that was 400x100 
(i.e. panorama) and wanted to fill a rect (say 200x180), your code would
    - get true for the first if-test (image is wider than high)
       - then get false for the inner if-test (rect is not taller than wide)
             (so picking the second set of calculations to do)
       - then calculate 400 / 200 ---> 2.0 for tRatio
       - set the width to 200 (correctly)
       - set the height to 100 / 2 ---> 50, so not filling the rect.


The easy way to solve the scaling part of this one is to remember that 
you want to scale the image by the same ratio in both directions, and 
that the ratio to use should be the value that will fill the rect in 
both dimensions. So you do something like (beware : untested code !!)

on resizeImage pImageID,fRectH,fRectW
   put the formattedWidth of pImageID into fImageW
   put the formattedHeight of pImageID into fImageH

put fRectH / fImageH into tH
    put fRectW / fImageW into tW
    put max(tH, tW) into tRatio

    set the width of image pImageID to tRatio * fImageW
    set the height of image pImageID to tRatio * fImageH
    ...

on the same example as above, this gets
    180 / 100 --> 1.8 for tH
    200 / 400 ---> 0.5 for tW
    1.8 ---> tRatio
and therefore sets the image width to 400*1.8 (i.e. 720) and the height 
to 100*1.8 (i.e. 180)
so an awful lot gets clipped, but it does fill the rect.


-- Alex.



On 15/10/2013 21:57, Dan Friedman wrote:
> Craig,
>
> Thanks for replying.  I am aware of the width and height properties.  But, I guess I can't manage it.  Perhaps you might take a look at this snippet and see what I'm doing wrong.  This works - but not always.
>
> on resizeImage pImageID,fRectH,fRectW
>    put the formattedWidth of pImageID into fImageW
>    put the formattedHeight of pImageID into fImageH
>    
>    try
>      if fImageW > fImageH then
>        if fRectW < fRectH then
>          --it's taller than wide
>          put fImageH / fRectH into tRatio
>          put fImageW / tRatio into tWidth
>          set the width of pImageID to tWidth
>          set the height of pImageID to fRectH
>        else
>          put fImageW / fRectW into tRatio
>          put fImageH / tRatio into tHeight
>          set the width of pImageID to fRectW
>          set the height of pImageID to tHeight
>        end if
>      else
>        --the image is higher than tall
>        if fRectW < fRectH then
>          --the area is taller then wide
>          put fImageH / fRectH into tRatio
>          put fImageW / tRatio into tWidth
>          set the width of pImageID to tWidth
>          set the height of pImageID to fRectH
>        else
>          --the area is wider then tall
>          put fImageW / fRectW into tRatio
>          put fImageH / tRatio into tHeight
>          set the width of pImageID to fRectW
>          set the height of pImageID to tHeight
>        end if
>      end if
>    end try
>    
>    set the loc of pImageID to fRectW/2,fRectH/2
> end resizeImage
>
>
>
>
>> So the aspect ratio is to remain constant, that is, the ratio of width to height.
>>
>> If you want to scale the image, this ratio must be maintained. If the new rect, for example is to be 1,5 times as wide as the old, but the new height is only 1,4 times as tall as the old, then the larger (width) value has to be used for both, and the excess height cropped. Similarly, if the image is scaled down, the larger value is to be "filled", and the other cropped. In all cases, the ratio is maintained.
>>
>> Using the several properties, "width", "height", "rect", "topLeft", etc, can you manage this? Write back if not, but it will be a terrific exercise for learning, and you should try first.
>>
>> Craig Newman
>>
>
>>> Greetings!
>>>
>>> I have been piddling around with this for weeks and still can't get it right.  I
>>> kinda got it working... but it's still not always 100% correct.  So, I thought I
>>> would ask this list for assistance since most of the people here are far smarter
>>> than I!
>>>
>>> You have a rect and an image.  The goal is to completely fill the rect with the
>>> image.  But, we don't want to distort the image.  So, you need to proportionally
>>> scale the image up (if the image is smaller than the rect) or down (if the image
>>> is larger than the rect).   Remember that we want to completely fill rect.  It's
>>> ok (and expected) that some of the image will be cropped.
>>>
>>> Think of this as setting the background of a stack with an image.  You want to
>>> fill the entire background of the stack (regardless of the size of the stack),
>>> with the image (regardless of the rect of the image).  But we don't want to
>>> distort the image.
>>>
>>> Any thoughts?
>>>
>>> -Dan
>>>
>
> _______________________________________________
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode




More information about the use-livecode mailing list