psychopy.org | Reference | Downloads | Github

Position property of BufferImageStim isn't used correctly

#1

Hi all, hoping you can help me iron out a problem I’m having with using BufferImageStim.

Basically, the pos arugment to BufferImageStim doesn’t seem to work as expected. Setting pos to anything other than (0, 0) causes the stimuli to not be displayed, and I think it’s being drawn “off screen”.

Consider the two examples of using BufferImageStim below. The first one takes a screenshot which is to be positioned at pos=(0, 0), which works fine. But the second one uses pos=(-.25, .25) and the screenshot stimuli isn’t shown anywhere on screen.

from psychopy import visual, core

win = visual.Window(size=(500, 500))
rect = visual.Rect(win, width=1.5, height=1.5, fillColor="#000000", lineColor="#0000FF")
circle = visual.Circle(win, radius=.5, fillColor="#FFFFFF", lineColor="#0000FF")

rect.draw()
circle.draw()
win.flip()
core.wait(2)

# Screenshot square where circle is inscribed. Works fine.
shot = visual.BufferImageStim(win, stim=[rect, circle], rect=[-.5, .5, .5, -.5])
shot.draw()
win.flip()
core.wait(2)

rect.draw()
circle.draw()
win.flip()
core.wait(2)

# No where to be seen!.
shot = visual.BufferImageStim(win, stim=[rect, circle], pos=(-.25, .25), rect = [-.5, .5, .5, -.5])
shot.draw()
win.flip()
core.wait(2)

I think the likely cause of the issue is conflicting units - the BufferImageStim object has properties specified in pixels, while the window uses normalized units. I’m confused about why this conflict happens though, because everything works as expected when using a vanilla ImageStim object specified in pixel units, and BufferImageStim inherits from ImageStim.

Any help in understanding/fixing this is appreciated!

P.S. If you’re a BufferImageStim expert, please have a look at my other thread here: Incorrect coordinates for bounding rect in BufferImageStim?, thanks!

#2

I was having similar problems moving the BufferImageStim dynamically, so I rewrote the draw function as follows:

    def draw(self, win=None):
        """Draws the BufferImage on the screen, similar to
        :class:`~psychopy.visual.ImageStim` `.draw()`.
        Allows dynamic position, size, rotation, mirroring, and opacity.
        Limitations / bugs: not sure what happens with shaders and
        self._updateList()
        """
        if win is None:
            win = self.win
        self._selectWindow(win)

        GL.glPushMatrix()  # preserve state
        win.setScale('pix')
        # GL.glLoadIdentity()

        # dynamic flip
        #GL.glScalef(self.thisScale[0] * (1, -1)[self.flipHoriz],
        #            self.thisScale[1] * (1, -1)[self.flipVert], 1.0)

        # enable dynamic position, orientation, opacity; depth not working?
        GL.glColor4f(self.desiredRGB[0], self.desiredRGB[1],
                     self.desiredRGB[2], self.opacity)

        #if self._needTextureUpdate:
        #    self.setImage(value=self._imName, log=False)
        if self._needUpdate:
            self._updateList()

        GL.glCallList(self._listID)  # make it happen
        GL.glPopMatrix()  # return the view to previous state

You’ll have to change your BufferImageStim units and size to be appropriate to your needs, but it works for me with that update.