Scaling an Image to a Rect

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Scaling an Image to a Rect

Dan Friedman
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
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

dunbarxx
Hi.


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




-----Original Message-----
From: Dan Friedman <[hidden email]>
To: use-livecode <[hidden email]>
Sent: Tue, Oct 15, 2013 4:11 pm
Subject: Scaling an Image to a Rect


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
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

 
_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

Dan Friedman
In reply to this post by Dan Friedman
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
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

mwieder
In reply to this post by Dan Friedman
Dan Friedman <dan@...> writes:

So, I thought I would ask this list for assistance since most of the
> people here are far smarter than I!

Well, I don't know about the smarter part, but here's what I do to generate
thumbnail images. It seems that you have the scaling options already worked
out, so I simplified this to just dealing with square images. I think what
you're missing is just locking the image and setting its text.


/**
 * ----------------------------------------
 * CreateThumbnail
 *
 * create a thumbnail image from the source image
 *
 * @pSourceImage : id of the image
 * @pNewWidth contains the width of the thumbnail image
 * @pNewHeight contains the height of the thumbnail image
 * ----------------------------------------
 */
function CreateThumbnail pSourceImage, pNewWidth, pNewHeight
   lock screen
   import snapshot from control id pSourceImage
   set the resizequality of the last image to "best"
   set the width of the last image to pNewWidth
   set the height of the last image to pNewHeight
   unlock screen
   return the id of the last image
end CreateThumbnail

on mouseUp
   local tTempImage
   
   -- create a 40x40 pixel thumbnail image from a square source image
   lock screen
   put CreateThumbnail(the id of image "image 1", 40, 40) into tTempImage
   set the width of image "image 2" to 40
   set the height of image "image 2" to 40
   set the lockloc of image "image 2" to true
   set the text of image "image 2" to the text of image id tTempImage
   delete image id tTempImage
   unlock screen
end mouseUp

--
 Mark Wieder
 [hidden email]




_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
--
 Mark Wieder
 ahsoftware@gmail.com
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

Alex Tweedly
In reply to this post by Dan Friedman
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
> [hidden email]
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

Richard Gaskin
In reply to this post by mwieder
Mark Wieder wrote:
> ...here's what I do to generate thumbnail images...

You probably already know this, but in order to make the new Project
Browser the RunRev team added the ability to create thumbnails from the
import and export commands with the addition of "at" args:

    import snapshot [from rect[angle] rectangle] [of object]
      [(with | without) effects] [at size width, height]

You still need to calculate the desired width and height, but the time
saved by letting the engine do this on the image buffer internally
rather than resizing an image and re-setting its contents is pretty amazing.

--
  Richard Gaskin
  Fourth World
  LiveCode training and consulting: http://www.fourthworld.com
  Webzine for LiveCode developers: http://www.LiveCodeJournal.com
  Follow me on Twitter:  http://twitter.com/FourthWorldSys

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

mwieder
Richard Gaskin <ambassador@...> writes:

> You probably already know this, but in order to make the new Project
> Browser the RunRev team added the ability to create thumbnails from the
> import and export commands with the addition of "at" args:
>
>     import snapshot [from rect[angle] rectangle] [of object]
>       [(with | without) effects] [at size width, height]

Ah... no, I missed that. I knew about the effects setting, but not the size
setting. I think "at" is a bit of a weird preposition in that context, but I
guess the engine's parser has its limits. Thanks.

--
 Mark Wieder
 [hidden email]




_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
--
 Mark Wieder
 ahsoftware@gmail.com
Reply | Threaded
Open this post in threaded view
|

RE: Scaling an Image to a Rect

FlexibleLearning.com
In reply to this post by Dan Friedman
Depends if you mind 'losing the cropped data' or not.

An alternative to Richard's elegant snapshot solution, which would lose the
cropped data, is a fixed location group where the resized image's width or
height fits the group width or height. Any excess image is not lost, simply
not visible. Also means you can use your existing proportional width/height
scaling routines.

Hugh Senior
FLCo



From: Richard Gaskin <[hidden email]>
To: [hidden email]
Sent: Tue, 15 Oct 2013 16:00:43 -0700
Subject: Re: Scaling an Image to a Rect

You probably already know this, but in order to make the new Project
Browser the RunRev team added the ability to create thumbnails from the
import and export commands with the addition of "at" args:

    import snapshot [from rect[angle] rectangle] [of object]
      [(with | without) effects] [at size width, height]

You still need to calculate the desired width and height, but the time
saved by letting the engine do this on the image buffer internally
rather than resizing an image and re-setting its contents is pretty amazing.

--
  Richard Gaskin


From: Dan Friedman <[hidden email]>
To: use-livecode <[hidden email]>
Sent: Tue, Oct 15, 2013 4:11 pm
Subject: Scaling an Image to a Rect


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
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

mwieder
Hugh-

Tuesday, October 15, 2013, 9:12:08 PM, you wrote:

> An alternative to Richard's elegant snapshot solution, which would lose the
> cropped data,

Dang. So the "at" clause is for cropping, not resizing.
While I'm happier about the syntax, I'm less than thrilled with the
effect. And here I was about to rewrite some code...

--
-Mark Wieder
 [hidden email]


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
--
 Mark Wieder
 ahsoftware@gmail.com
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

Richard Gaskin
Mark Wieder wrote:

> Hugh-
>
> Tuesday, October 15, 2013, 9:12:08 PM, you wrote:
>
>> An alternative to Richard's elegant snapshot solution, which would lose the
>> cropped data,
>
> Dang. So the "at" clause is for cropping, not resizing.
> While I'm happier about the syntax, I'm less than thrilled with the
> effect. And here I was about to rewrite some code...

I'm not sure what Hugh was referring to, but the "at" clause is indeed
for resizing.  Remember, it was added for the IDE's Project Browser,
which makes complete thumbnails of controls.

Try it....

--
  Richard Gaskin
  Fourth World
  LiveCode training and consulting: http://www.fourthworld.com
  Webzine for LiveCode developers: http://www.LiveCodeJournal.com
  Follow me on Twitter:  http://twitter.com/FourthWorldSys

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

Jim Lambert
In reply to this post by Dan Friedman
MarkW wrote:

> Subject: Re: Scaling an Image to a Rect
> Message-ID: <[hidden email]>
> Content-Type: text/plain; charset=us-ascii
>
> Richard Gaskin <ambassador@...> writes:
>
>> You probably already know this, but in order to make the new Project
>> Browser the RunRev team added the ability to create thumbnails from the
>> import and export commands with the addition of "at" args:
>>
>>    import snapshot [from rect[angle] rectangle] [of object]
>>      [(with | without) effects] [at size width, height]
>
> Ah... no, I missed that. I knew about the effects setting, but not the size
> setting. I think "at" is a bit of a weird preposition in that context, but I
> guess the engine's parser has its limits. Thanks.


Just remember the 'at size' extension doesn't seem to work with all variations of the 'import snapshot' command.

WORKS:
import snapshot from image "dummy" at size 100,100
import snapshot from this card at size 100,100

DOESN'T WORK:
import snapshot from rectangle 0,0,300,300 at size 100,100
import snapshot from rectangle (the rect of image "dummy") at size 100,100

Jim Lambert

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

Richard Gaskin
Jim Lambert wrote:

 > Just remember the 'at size' extension doesn't seem to work with all
 > variations of the 'import snapshot' command.
 >
 > WORKS:
 > import snapshot from image "dummy" at size 100,100
 > import snapshot from this card at size 100,100
 >
 > DOESN'T WORK:
 > import snapshot from rectangle 0,0,300,300 at size 100,100
 > import snapshot from rectangle (the rect of image "dummy") at size
 > 100,100

Given the reason "at" was added (for the Project Browser thumbnails),
and the generally more useful object-rendered snapshots vs snippets of
the composite buffer, it's not surprising that this extension is limited
as it is.

Still, for the sake of completeness and consistency it may be useful to
file an enhancement request for that.

Anyone here know if one has been submitted?  I've been having bad luck
with the RQCC's search lately.

--
  Richard Gaskin
  Fourth World
  LiveCode training and consulting: http://www.fourthworld.com
  Webzine for LiveCode developers: http://www.LiveCodeJournal.com
  Follow me on Twitter:  http://twitter.com/FourthWorldSys


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

BNig
This post has NOT been accepted by the mailing list yet.
In reply to this post by Jim Lambert
See also

"export snapshot from rect with at size refuses to compile"

Bug #11145

http://quality.runrev.com/show_bug.cgi?id=11145

Kind regards
Bernd

Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

BNig
In reply to this post by Richard Gaskin
See also

"export snapshot from rect with at size refuses to compile"

Bug #11145

http://quality.runrev.com/show_bug.cgi?id=11145

Kind regards
Bernd
Reply | Threaded
Open this post in threaded view
|

Re: Scaling an Image to a Rect

Geoff Canyon-4
In reply to this post by Dan Friedman
Late to the party, but this command takes the long id of an image and a
width and height and resizes the image appropriately. The default is (I
think) what you're looking for, but you can also pass in true for bFit and
get the reverse: the image is still proportional, but instead of filling
the width and height (and potentially overflowing one of them in order to
maintain proportions) it fits within them. It doesn't do any math it
doesn't have to do, and it resizes the image in one statement (faster I
think than setting the height and width separately).

on resizeImage pID,H,W,bFit
   -- pID: long id of the image to resize
   -- H: the height of the rect to use
   -- W: the width of the rect to use
   -- bFit: if true, fit the image in the rect
   --        if false or empty (default), fill the rect with the image

   put the formattedWidth of pID into fW
   put the formattedHeight of pID into fH
   put H / fH into hRatio
   put W / fW into wRatio
   put the rect of pID into R

   if (hRatio > wRatio) is (bFit is true) then
      put round(item 1 of R + W) into item 3 of R
      put round(item 2 of R + fH * wRatio) into item 4 of R
   else
      put round(item 1 of R + fW * hRatio) into item 3 of R
      put round(item 2 of R + H) into item 4 of R
   end if
   set the rect of pID to R
end resizeImage



On Tue, Oct 15, 2013 at 3:10 PM, Dan Friedman <[hidden email]>wrote:

> 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
> [hidden email]
> Please visit this url to subscribe, unsubscribe and manage your
> subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode
>
_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode