display images with different aspect ratios and fixing one dimension

531 views
Skip to first unread message

John Allen

unread,
Mar 8, 2013, 11:41:47 AM3/8/13
to psychop...@googlegroups.com
Hi,

I'm using the coder view and looking at using ImageStim to display a variety of images (whatever it finds in a folder)

These images can vary in aspect ratio though they all have a fixed height.

I'd like to display these but I need to rescale them to fit.

How can I just specify just one dimension (height) and let the width vary whilst maintaining the original aspect ratio so that I don't get any abnormal stretching?

Thanks,

John

John Allen

unread,
Mar 8, 2013, 12:11:28 PM3/8/13
to psychop...@googlegroups.com
Actually, this seems to have the desired affect:

        tmp=Image.open(imgFile)
        imgStim = visual.ImageStim( mywin, imgFile, pos=(0.0,0.5 ), size=(0.4 * tmp.size[0]/tmp.size[1],0.4))

where 0.4 produces the desired scaling factor for my fixed height images with varying widths.

there's probably a neater solution though.

Chris Cox

unread,
Mar 8, 2013, 1:43:22 PM3/8/13
to psychop...@googlegroups.com
Hi John,

I think you've hit on a good solution here.  One way that you might make things cleaner is by adding a method to the ImageStim class, just for the duration of the current program.  You should be careful that you aren't overwriting a property or method that already exists in the class, but otherwise I don't see any danger in doing this.  This does not make any persistent changes to visual.ImageStim.

So, I basically took your scaling method and wrapped it into a function, and stuck that function into the ImageStim class on the fly.  The function could be better written... but it works.  Let me know if you like this solution! I only just realized this was possible about 30 minutes ago. ;)


HTH!
Chris



--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/psychopy-users/-/gG0hWn6BmLYJ.

For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jonathan Peirce

unread,
Mar 9, 2013, 5:21:41 AM3/9/13
to psychop...@googlegroups.com
When an image is imported I think its original size will be tracked with an origSize attribute. So you can avoid loading the image twwice from disk, which you're doing right now by doing

imgStim = visual.ImageStim( mywin, imgFile, pos=(0.0,0.5 ))
imgStim.setSize( [imgStim.origSize[0]*0.4, imgStim.origSize[1]*0.4] )

And actually, as I wrote that I realised you could also use the fact that nearly all set____ methods in psychopy also support an operator that allows you to add/subtr/multiply... the current value. So you could also do

imgStim = visual.ImageStim( mywin, imgFile, pos=(0.0,0.5 ))
imgStim.setSize(0.4, '*') #multiply the current size by 0.4

Jon
--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/psychopy-users/-/gG0hWn6BmLYJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

-- 
Jonathan Peirce
Nottingham Visual Neuroscience

http://www.peirce.org.uk/

John Allen

unread,
Mar 10, 2013, 12:33:09 PM3/10/13
to psychop...@googlegroups.com
Hi Chris,

Thanks for this. Really great to see how easy it is to add new methods on the fly to the existing built-ins. I don't htink I'd have thought of doing that but I'm sure I will in future as the abstracting keeps things nice and clean.

I think in this instance I'll use Jon's suggestion below but many thanks none-the-less,

cheers,

John

John Allen

unread,
Mar 10, 2013, 12:34:04 PM3/10/13
to psychop...@googlegroups.com
Thanks, Jon - an interesting insight into the inner workings :)

cheers,

john

Jonas Lindeløv

unread,
Sep 16, 2014, 7:19:55 AM9/16/14
to psychop...@googlegroups.com
To add to this, Jon's answer is the simplest way to go if you just want to scale with some fixed amount, e.g. to 40% in his example. But if you want to scale to some fixed size using 'cm', 'deg' etc as units, the simplest solution I could come up with was this:

imageSize = 10  # scale the image's maximum dimension to this and the other proportionally
image
= visual.ImageStim(win, 'someImage.png')  # image.size is e.g. [17.0245, 9.3434]
image
.size *= imageSize / max(image.size)  # change max to min if you want this to apply to the minimum length.

... and now image.size should be [imageSize, something]

Best,
Jonas

On Saturday, March 9, 2013 11:21:41 AM UTC+1, Jon wrote:
When an image is imported I think its original size will be tracked with an origSize attribute. So you can avoid loading the image twwice from disk, which you're doing right now by doing

imgStim = visual.ImageStim( mywin, imgFile, pos=(0.0,0.5 ))
imgStim.setSize( [imgStim.origSize[0]*0.4, imgStim.origSize[1]*0.4] )

And actually, as I wrote that I realised you could also use the fact that nearly all set____ methods in psychopy also support an operator that allows you to add/subtr/multiply... the current value. So you could also do

imgStim = visual.ImageStim( mywin, imgFile, pos=(0.0,0.5 ))
imgStim.setSize(0.4, '*') #multiply the current size by 0.4

Jon

On 08/03/2013 17:11, John Allen wrote:
Actually, this seems to have the desired affect:

        tmp=Image.open(imgFile)
        imgStim = visual.ImageStim( mywin, imgFile, pos=(0.0,0.5 ), size=(0.4 * tmp.size[0]/tmp.size[1],0.4))

where 0.4 produces the desired scaling factor for my fixed height images with varying widths.

there's probably a neater solution though.

On Friday, March 8, 2013 4:41:47 PM UTC, John Allen wrote:
Hi,

I'm using the coder view and looking at using ImageStim to display a variety of images (whatever it finds in a folder)

These images can vary in aspect ratio though they all have a fixed height.

I'd like to display these but I need to rescale them to fit.

How can I just specify just one dimension (height) and let the width vary whilst maintaining the original aspect ratio so that I don't get any abnormal stretching?

Thanks,

John
--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psychopy-users+unsubscribe@googlegroups.com.
To post to this group, send email to psychopy-users@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msg/psychopy-users/-/gG0hWn6BmLYJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Chuck Theobald

unread,
Sep 24, 2014, 6:53:34 PM9/24/14
to psychop...@googlegroups.com
This may be a stylistic difference, but my way of doing this is as follows (for a dictionary "images" of ImageStim):

for img in images:
    scalingFactor = newImageHeight / images[img].size[1]
    images[img].size *= scalingFactor

Here I scale each image to a set height, "newImageHeight", while preserving aspect ratio.

Another kind of interesting thing about this approach is that the key "img" is an md5 hash of the image file name. The input file to the program contains a line for each stimulus file, and this avoids loading the same file into memory more than once. The experiment I am programming has the possibility of showing the same image more than once.
Reply all
Reply to author
Forward
0 new messages