The template picture is almost identical to text, except that images are loaded from JPG files and displayed instead of text.
These are the files used to build picture. Those that are the same as for text are marked with an asterisk.
picture.h | Declarations to link together the template experiment files. Most of the declarations in this file can be used in your experiments. |
main.c * | WinMain() function for windows non console compilation and main() for other compilations, setup and shutdown link and graphics, open EDF file. |
trials.c | Called to run a block of trials for the "picture" template. Performs system setup at the start of each block, then runs the trials. Handles standard return codes from trials to allow trial skip, repeat, and experiment abort. This file can be modified for your experiments, by replacing the trial instance code. |
trial.c | Implements a trial with simple graphics that can be drawn in one screen refresh, and therefore doesn't need display blanking. You should be able to use this by replacing the drawing code, message code, and handling any participant responses. |
The only difference is the block loop module (trials.c), and the use of IMG_Load to load an image file as a bitmap. The same trial recording file (trial.c) as in text template is used to display the stimuli and record data.
The first difference from the trials.c in text template is the color of the background. This is medium gray, matching the average luminance of the pictures. In a real experiment, each picture may have a different average luminance, and the calibration background color should be reset before each trial so that the drift correction background matches the image.
SETCOLOR(target_background_color,128,128,128); // This should match the displayset_calibration_colors(&target_foreground_color, &target_background_color);
The function do_picture_trial()
is used to setup and run the picture- presentation trials. The trial bitmap is created by calling create_image_bitmap()
. The bitmap_to_backdrop()
function transfers the image bitmap over the link to the tracker PC as a backdrop for gaze cursors (Unlike the previous TEXT template, the image is not saved). The image bitmap is then passed to bitmap_recording_trial()
, where it is copied to the display at the proper time. After the trial, be sure to delete the bitmap.
char *images[3] = { "images/sacrmeto.jpg", "images/sac_blur.jpg", "images/composite.jpg" };int do_picture_trial(int num){SDL_Surface * bitmap;int i;// This supplies the title at the bottom of the eyetracker displayeyecmd_printf("record_status_message '%s, TRIAL %d/%d' ",imgname[num-1],num, NTRIALS);// Always send a TRIALID message before starting to record.// It marks the start of the trial and should precede any other messageseyemsg_printf("TRIALID PIX%d %s", num, imgname[num - 1]);// !V TRIAL_VAR message is recorded for EyeLink Data Viewer analysis// It specifies a trial variable and value for the given trial// This must be specified within the scope of an individual trial (i.e., after// "TRIALID" and before "TRIAL_RESULT")eyemsg_printf("!V TRIAL_VAR trial %d", num);eyemsg_printf("!V TRIAL_VAR type %s", imgname[num - 1]);set_offline_mode();// Must be offline to draw to EyeLink screenbitmap = create_image_bitmap(num-1);if(!bitmap){alert_printf("ERROR: could not create image %d", num);return SKIP_TRIAL;}// NOTE:** THE FOLLOWING TEXT SHOULD NOT APPEAR IN A REAL EXPERIMENT!!!!clear_full_screen_window(target_background_color);get_new_font(NULL, 24, 0);graphic_printf(window,target_foreground_color, CENTER, SCRWIDTH/2,SCRHEIGHT/2, "Sending image to EyeLink...");Flip(window);// Transfer bitmap to tracker as backdrop for gaze cursorsbitmap_to_backdrop(bitmap, 0, 0, 0, 0,0, 0,// record the triali = bitmap_recording_trial(bitmap, 20000L);SDL_FreeSurface(bitmap);return i;}
The first two trials of the current template load a normal picture (sacrmeto.jpg) and a blurred one (sac_blur.jpg) by calling image_file_bitmap()
. The last trial creates a composite image from four smaller images (hearts.jpg, party.jpg, purses.jpg, and squares.jpg) by using composite_image()
. This is achieved by first creating a blank bitmap (blank_bitmap()
) and then loading individual images and adding them to the blank bitmap at a specific (x, y) position with the add_bitmap()
function.
In this example, the bitmap is magnified or reduced to fill the display. This will degrade the image somewhat and slows loading, so it may be important to match the display mode to the original image file resolution. Alternatively, if the size is set to (0, 0), the picture is not resized but is simply clipped or centered on the display. Alternatively, the image may be loaded to a bitmap of identical size, and this bitmap copied to a blank bitmap to create a composite display with several pictures and text.
Because loading and resizing images can take significant time, this sample code displays a message while the picture is loading. This would not be desirable in a real experiment, of course. It is important to check that the picture loaded successfully before running the trial.
// Adds individual pieces of source bitmap to create a composite picture// Top-left placed at (x,y)// If either the width or height of the display is 0, simply copy the bitmap// to the display without chaning its size. Otherwise, stretches the bitmap to to// fit the dimensions of the destination display areaint add_bitmap(SDL_Surface * src, SDL_Surface * dst, int x, int y, int width, int height){SDL_Rect dstrect = {x,y,width,height};SDL_Rect srcrect = {0,0,width,height};if(src->w != srcrect.w || src->h != srcrect.h){double zx = (double)srcrect.w/(double)src->w;double zy = (double)srcrect.h/(double)src->h;SDL_Surface *resized = zoomSurface(src,zx,zy,0);if(resized)src = resized;}SDL_BlitSurface(src,&srcrect,dst,&dstrect);return 0;}// Creates a composite bitmap based on individual piecesSDL_Surface * composite_image(void){int i = 0;// Handle to the background and foreground bitmapsSDL_Surface* bkgr;SDL_Surface* img;SDL_Rect points[4];char *small_images_nopath[4];// Filenames of the four small imagessmall_images_nopath[0]="images/hearts.jpg";small_images_nopath[1]="images/party.jpg";small_images_nopath[2]="images/squares.jpg";small_images_nopath[3] ="images/purses.jpg";// The x,y coordinates of the top-left corner of the region where// the individual small image is displayedpoints[0].x=0; points[0].y=0;points[1].x=SCRWIDTH/2; points[1].y=0;points[2].x=0; points[2].y=SCRHEIGHT/2;points[3].x=SCRWIDTH/2; points[3].y=SCRHEIGHT/2;// Create a blank bitmap on which the smaller images are overlaidbkgr = SDL_CreateRGBSurface(SDL_SWSURFACE,SCRWIDTH,SCRHEIGHT,dispinfo.bits,0,0,0,0);if(!bkgr)return NULL;SDL_FillRect(bkgr,NULL,SDL_MapRGB(bkgr->format, 128,128,128));// loop through four small imagesfor (i=0; i<4; i++){// Load the small images, keep the original size// If the image can not be loaded, delete the created blank bitmap;img = image_file_bitmap(small_images_nopath[i], 1, 0, 0, 0);if(!img){SDL_FreeSurface(bkgr);return NULL;}// Add the current bitmap to the blank bitmap at x, y position,// resizing the bitmap to the specified width and height// If the original size is to be kept, set the width and// height paremeters to 0add_bitmap(img, bkgr, points[i].x, points[i].y, SCRWIDTH/2, SCRHEIGHT/2);// IMGLOAD command is recorded for EyeLink Data Viewer analysis// It displays a default image on the overlay mode of the trial viewer screen.// Writes the image filename + path info// The IMGLOAD TOP_LEFT command specifies an image to use as a segment of the// spatial overlay view with specific top left x,y coordinates and image width and heightcopy_resource_to_output_folder(small_images_nopath[i]);eyemsg_printf("!V IMGLOAD TOP_LEFT %s %d %d %d %d", small_images_nopath[i],points[i].x, points[i].y, SCRWIDTH/2, SCRHEIGHT/2);// IAREA command is recorded for EyeLink Data Viewer analysis// Another way of handling segment information by recording the content field// in IAREA RECTANGLE command.// The fields are: segment id, (x, y) coordinate of top-left and bottom-right positionseyemsg_printf("!V IAREA RECTANGLE %d %d %d %d %d %s",i+1, points[i].x, points[i].y,points[i].x + SCRWIDTH/2, points[i].y + SCRHEIGHT/2, small_images_nopath[i]);// Be sure to delete bitmap handle before re-using it.SDL_FreeSurface(img);}// If the operation is successful, the background image is now// overlaid with the smaller imagesreturn bkgr;}