FAQ - How do I take a screen shot of my stimuli?
Q: How do I take a screen shot of my stimuli?
A:Via the PTB-3 function GetImage
PTB-3 is based around a dual buffer system; you send draw commands to a back buffer (offscreen) then 'flip' that back buffer to the front, where it will be displayed. The Screen subfunction GetImage can read from either buffer, defaulting to reading the front.
GetImage returns a matrix of RGB values that can be converted to an image via the Matlab function imwrite. Different image formats require different arguments; refer to the help for imwrite for more detail.
Common problems:
1. The output image is blank
Ensure GetImage is recording from the correct buffer, and ensure you have a suitable graphics card.
2. imwrite returns errors
Double check you have sent the correct format imageArray to imwrite - different image file formats have different rules and the return value from GetImage may need to be converted. Refer to the imwrite documentation.
Example code:
function imageArray = testImageWriting
%Draws an oval in the top left corner of the screen, and outputs a jpg image of that dot.
try
wPtr = Screen('OpenWindow', 0);
HideCursor;
Screen('FillRect', wPtr, 0); Screen(wPtr, 'Flip');
white = WhiteIndex(wPtr);
%Draws the display to be turned into an image file
a = [100 100 150 150]';
b = [100 200 150 200]';
ovalSpecs = [a b];
Screen('FillOval', wPtr, white, ovalSpecs ); Screen(wPtr, 'Flip');
%GetImage call. Alter the rect argument to change the location of the screen shot
imageArray = Screen('GetImage', wPtr, [0 0 300 300]);
%imwrite is a Matlab function, not a PTB-3 function
imwrite(imageArray, 'test.jpg')
WaitSecs(.5);
ShowCursor;
Screen('CloseAll');
catch
ShowCursor;
Screen('CloseAll');
endfunction imageArray = movingDots
%Produces a dynamic display and outputs an animated .gif record of the trial
imageArray={};
try
[wPtr, rect] = Screen('OpenWindow', 0)
HideCursor;
Screen('FillRect', wPtr, 0); Screen(wPtr, 'Flip');
%Animation parameters
centre = rect(3)/2;
dotDiameter = 50;
yTop = 304;
amplitude = 300;
frequency = 1;
white = WhiteIndex(wPtr);
%Draws the display to be turned into an image file
start=GetSecs;
while GetSecs<start+2
time = GetSecs-start;
oval = centre + (amplitude * cos(frequency * time *(2*pi)));
ovalSpecs = [oval yTop oval+dotDiameter yTop+dotDiameter]';
%You can try calling GetImage at this point prior to the call to 'Flip' and specifying the backbuffer
Screen('FillOval', wPtr, white, ovalSpecs); Screen(wPtr, 'Flip');
%Records the frame from front buffer and appends to the imageArray matrix
%Assumes a screen resolution of 1024x768; alter the rect coordinates to change this
imageArray=[imageArray; {Screen('GetImage', wPtr, [200 264 874 544])}];
end
ShowCursor;
Screen('CloseAll');
%Creates the .gif
delayTime = 1/60; %Screen refresh rate of 60Hz
for i=1:length(imageArray)
%Gifs can't take RBG matrices: they have to be specified with the pixels as indices into a colormap
%See the help for imwrite for more details
[y, newmap] = cmunique(imageArray{i});
%Creates a .gif animation - makes first frame, then appends the rest
if i==1
imwrite(y, newmap, 'Zero Phase.gif');
else
imwrite(y, newmap, 'Zero Phase.gif', 'DelayTime', delayTime, 'WriteMode', 'append');
end
end
catch
ShowCursor;
Screen('CloseAll');
end