FAQ: Screenshots or Recordings - Psychtoolbox-3/Psychtoolbox-3 GitHub Wiki
Q: How do I take a screen shot of my stimuli?
A: Via the PTB-3 function Screen('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 frontbuffer.
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:
-
The output image is blank
Ensure
GetImage
is recording from the correct buffer, and ensure you have a suitable graphics card. -
imwrite
returns errorsDouble check you have sent the correct format imageArray to
imwrite
-- different image file formats have different rules and the return value fromGetImage
may need to be converted. Refer to theimwrite
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');
end
function 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
Q: How do I record a movie of my dynamic visual stimuli?
A: Via the functions Screen('CreateMovie', ...)
and Screen('AddFrameToMovie', ...)
.
movie = Screen('CreateMovie', ...);
allows to prepare movie recording of onscreen stimuli into a movie file, e.g., an AVI, Quicktime, Matroska or similar file format, encoded with modern video codecs like H264, H265 etc. You can specify the name of the movie file, the size of the images (width x height) stored in the movie, the type and encoding of the movie, the nominal framerate at which the movie should play back , the number of color channels and the color depth. Once the movie
handle has been created, you can use the command Screen('AddFrameToMovie', ...)
in the places and in the same way as you'd use the Screen('GetImage', ...)
command described above in the section about screen shots. Each call to Screen('AddFrameToMovie', ...)
will take a snapshot of a portion of the specified onscreen or offscreen window, but store the screen grabbed image in the created movie file, instead of returning the image as a Matlab matrix. At the end of a session, you call Screen('FinalizeMovie', ...)
to finish movie recording and create the final movie file. If you chose suitable movie formats and encoding parameters, the resulting movie file will not only play back with Psychtoolbox movie playback functions, but also with standard movie and video players. The approach is demonstrated in ImagingStereoDemo.m
if you pass it the optional writeMovie
parameter, e.g., ImagingStereoDemo([],[],1);
. A setting of 2 in that demo will also demonstrate how one can add an audio track to such a recorded movie with the help of the function Screen('AddAudioBufferToMovie', ...)
. On modern systems with modern graphics cards, movie recording should be possible for high resolution movies at reasonable performance. It may even use hardware accelerated video encoding if your graphics card supports this.