Hardcoding height of image

Hello,

I’m wondering if there is a way to hardcode the height of an image while allowing the width to adjust accordingly to the specs of each image?

I’m using builder view and can see that it is possible to specify dimensions, however my images are of different proportions and I need the width to adjust appropriately while keeping the height fixed.

Is there a way to do this in builder rather than code?

Thanks

1 Like

No, you’d need to do this with code I’m afraid. I do want to implement something where you would set an image size to, say, [None, 50] so that the height is set to 50 and the width just scales, but haven’t got there yet

2 Likes

Ok, thank you!

Hey Jon, if we were to want to implement something like this in code, would we have to define both width and height? I’m imagining a solution wherein you create a variable equal to the width of an image, updating it every time a new image is loaded, but just setting the height value to a constant ( like this visual.ImageStim(size=[x, 0.7]). I’m not sure if PsychoPy is designed to make this simpler though; like perhaps just leaving the varying dimension argument undefined might work. A friend just posed this question to me and I couldn’t find any clarification for how it might work.

Once an ImageStim has been created, it has an attribute called _origSize, which is essentially the size of the image itself (not the ImageStim) in pixels. If you divide image._origSize[1] by image._origSize[0] then you’ll have the ratio you’d need to multiply the width by to make it match a given height; or flip the two values around to get the inverse. So you could then do:

image.size = [x, x*(image._origSize[1] / image._origSize[0])]
or
image.size = [x*(image._origSize[0] / image._origSize[1]), x]

A note on this though: In norm units this won’t work as intended, as the two dimensions aren’t weighted equally. What you’d need to do for norm is a bit more complicated:

pix = layout.Size([x, None], units="norm", win=win).pix
pix[1] = pix[0] * (image._origSize[1] / image._origSize[0])
image.size = layout.Size(pix, units="pix", win=win)

or

pix = layout.Size([x, None], units="norm", win=win).pix
pix[0] = pix[1] * (image._origSize[0] / image._origSize[1])
image.size = layout.Size(pix, units="pix", win=win)

(converting back and forth from pix units like this means you can do uniform transformations, then convert back to norm to set the size)

As Jon said, we’d like to implement it such that image.size = [x, None] means it’s width is x and height is scaled to maintain aspect ratio, but this will take a bit of work to handle all the edge cases.