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');
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
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki