Drawing—images

Objectives

  • Be able to display stimuli formed from images stored in files on disk.
  • Understand the concept of transparency and its implications for drawing stimuli.
  • Know how to create screenshots of the stimulus window.

Drawing images from files on disk

While most vision science experiments involve stimuli that are generated rather than those that are loaded from images, there are still situations in which drawing images from files that are stored on disk is required. In psychopy, we can use ImageStim.

For example, we might want to draw the UNSW logo, which we have saved to disk as a file called UNSW.png. To draw this in Python code, we could do:

import psychopy.visual
import psychopy.event

win = psychopy.visual.Window(
    size=[400, 400],
    units="pix",
    fullscr=False
)

img = psychopy.visual.ImageStim(
    win=win,
    image="UNSW.png",
    units="pix"
)

img.draw()

win.flip()

psychopy.event.waitKeys()

We could also display the image in a larger size, although this would entail an inevitable loss in quality. This gets a bit complicated because we might not necessarily know the size of the image—we just know that we want to scale its size. We can use the image’s size property to sensibly increase the size of the image that we show:

import psychopy.visual
import psychopy.event

win = psychopy.visual.Window(
    size=[400, 400],
    units="pix",
    fullscr=False
)

img = psychopy.visual.ImageStim(
    win=win,
    image="UNSW.png",
    units="pix"
)

size_x = img.size[0]
size_y = img.size[1]

img.size = [size_x * 1.5, size_y * 1.5]

img.draw()

win.flip()

psychopy.event.waitKeys()

win.close()

Transparency and masking

You may notice in the above examples that the “background” in the image we display seems to match the colour of our window. This is because the image file has embedded in it the desired “transparency” of each pixel, which is respected by psychopy. We can see this more clearly if we draw the image after we have drawn a rectangle:

import psychopy.visual
import psychopy.event

win = psychopy.visual.Window(
    size=[400, 400],
    units="pix",
    fullscr=False
)

rect = psychopy.visual.Rect(
    win=win,
    width=200,
    height=100,
    pos=[0,-50],
    fillColor=[1] * 3
)

rect.draw()

img = psychopy.visual.ImageStim(
    win=win,
    image="UNSW.png",
    units="pix"
)

img.draw()

win.flip()

psychopy.event.waitKeys()

win.close()

In addition to such masking, we can also set the overall transparency (also known as “opacity”) of many stimulus types in psychopy using the opacity parameter. This means that successive drawing operations are blended with what has previously been drawn rather than completely overwriting them. For example, we could set the transparency of the image to 50%—notice how it is blended with other elements in the window:

import psychopy.visual
import psychopy.event

win = psychopy.visual.Window(
    size=[400, 400],
    units="pix",
    fullscr=False
)

rect = psychopy.visual.Rect(
    win=win,
    width=200,
    height=100,
    pos=[0,-50],
    fillColor=[1] * 3
)

rect.draw()

img = psychopy.visual.ImageStim(
    win=win,
    image="UNSW.png",
    units="pix"
)

img.opacity = 0.5

img.draw()

win.flip()

psychopy.event.waitKeys()

win.close()

Saving screenshot images

Finally, we will consider how we can take a “screenshot” of what we have drawn using psychopy. This is often a useful procedure, as it allows us to make figures in articles and reports on our research that give a sense of what stimuli participants were viewing.

We can save screenshots easily in psychopy via a two-step process. First, once we have flipped our window into a state that we would like to save, we can use the command win.getMovieFrame() to tell psychopy to save the current state of the window. Then, we use the command win.saveMovieFrames(img_path) to save this state to a file on disk, where img_path is the name of the file that we want to save it to. For example:

import psychopy.visual
import psychopy.event

win = psychopy.visual.Window(
    size=[400, 400],
    units="pix",
    fullscr=False
)

rect = psychopy.visual.Rect(
    win=win,
    width=200,
    height=100,
    pos=[0,-50],
    fillColor=[1] * 3
)

rect.draw()

img = psychopy.visual.ImageStim(
    win=win,
    image="UNSW.png",
    units="pix"
)

img.opacity = 0.5

img.draw()

win.flip()

win.getMovieFrame()
win.saveMovieFrames("unsw_logo_blend_example.png")

psychopy.event.waitKeys()

win.close()