Voici une implémentation qui permet d'interfacer la bibliothèque graphique SDL et MATLAB (à l'aide des MEX-Files). Cette implémentation a pour objectif d'afficher une image en niveaux de gris représentée sous forme matricielle dans MATLAB.

Il est nécessaire d'avoir les paquets suivants installés :

  • libsdl1.2debian
  • libsdl1.2-dev
  • libsdl-gfx1.2-dev


Après avoir installé la SDL et SDL_gfx voici le MEX-File :

Code C :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "mex.h"
 
#include<stdio.h>
#include<stdlib.h>
#include <SDL/SDL.h>
#include <SDL/SDL_rotozoom.h>
 
 
/* creation de la surface associee a l'image */
SDL_Surface *createImage(double **image,int height,int width)
{
	int i,j; 
 
	SDL_Surface *simage= NULL;
	SDL_Rect position;
 
	simage=SDL_CreateRGBSurface(SDL_HWSURFACE,width,height,32,0,0,0,0);
	position.w=position.h=1;
 
	for (i = 0 ; i < height; ++i){
		for(j=0;j<width;++j){
			position.x = j; 
			position.y = i;
			SDL_FillRect(simage,&position,SDL_MapRGB(simage->format,image[i][j],image[i][j],image[i][j]));
		}
	}
 
	return(simage);
}
 
/* affichage de l'image suivant sa taille */
 
void displayImage(SDL_Surface **ecran,SDL_Surface *simage,int height,int width)
{
	SDL_Surface *newSurf=NULL;
	SDL_Rect position;
	position.x = 0;
	position.y = 0;
 
 
	if(*ecran!=NULL) SDL_FreeSurface(*ecran); /*on efface l'ecran si c'est la premiere fois qu'il est utilise*/
 
	if(simage->w!=width || simage->h!=height) /*si le redimensionement change la taille de l'image on cree une nouvelle surface */
		newSurf=rotozoomSurfaceXY(simage,0.,(double)width/(double)simage->w,(double)height/(double)simage->h,1);
	else newSurf=simage;
 
	*ecran=SDL_SetVideoMode(newSurf->w,newSurf->h,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_RESIZABLE);
	SDL_BlitSurface(newSurf,NULL,*ecran,&position);
	SDL_Flip(*ecran);
 
	if(newSurf!=simage) 
		SDL_FreeSurface(newSurf);
}
 
 
 
/* Traitement des evenements */
void treatEvent(SDL_Surface **ecran,SDL_Surface *simage,int height,int width)
{
	int done;
	SDL_Event event;
 
	done=0;
 
	while(!done) {
		SDL_WaitEvent(&event);
 
		switch(event.type) {
		case SDL_QUIT: 
			done=1; 
			break;
 
		case SDL_KEYDOWN:
			switch(event.key.keysym.sym) {
			case SDLK_ESCAPE: 
				done=1; 
				break;
			default: 
				break;
			} 
			break;
 
 
		case SDL_VIDEORESIZE:
			displayImage(ecran,simage,event.resize.h,event.resize.w);
			break; 						
		} 
	}		
}
 
 
 
void affiche(double **image,int nrow,int ncol,int largeur_max,int hauteur_max)
{
	SDL_Surface *ecran,*imgSurf; 
	ecran=NULL;
 
 
	imgSurf=createImage(image,nrow,ncol); /*creation de la surface associee à l'image*/
 
	while(largeur_max<ncol || hauteur_max<nrow)  {nrow=nrow/2;ncol=ncol/2;}
 
	displayImage(&ecran,imgSurf,nrow,ncol); /*creation de l'image a l'ecran*/
	SDL_WM_SetCaption("My Picture SDL !", NULL); /*mettre un titre a la fenetre*/
 
	treatEvent(&ecran,imgSurf,nrow,ncol); /* gestion des evenements(clavier,redimensionement, ect...)*/
 
	/* liberation de la memoire */
	SDL_FreeSurface(imgSurf);
	SDL_FreeSurface(ecran);
 
	return;
}
 
 
 
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
 
	double *x=NULL, **image=NULL;
	mwSize nrow, ncol;
	mwIndex i,j;
	const SDL_VideoInfo *videoInfo;
	int largeur_max,hauteur_max;
 
	nrow = mxGetM(prhs[0]);
	ncol = mxGetN(prhs[0]);
 
	/* changement de representation en memoire des matrices*/
	x=mxGetPr(prhs[0]);   
 
	image=mxMalloc(nrow*sizeof(double *));
	image[0]=mxMalloc(nrow*ncol*sizeof(double));
	for (i=1;i<nrow;++i)
		image[i]=image[i-1]+ncol;
 
	for(i=0;i<nrow;++i)
		for(j=0;j<ncol;++j)
			image[i][j]=x[j*nrow+i];;
 
 
	/*############## affichage des resultats en fenetre ############*/                      
	SDL_Init(SDL_INIT_VIDEO);
 
	videoInfo=SDL_GetVideoInfo();  /*determination de la taille de l'ecran*/
	largeur_max=videoInfo->current_w;
	hauteur_max=videoInfo->current_h;
 
	affiche(image,nrow,ncol,largeur_max,hauteur_max); 
 
	SDL_Quit();
 
	/* liberation de la memoire */
	mxFree(image[0]); 
	mxFree(image);
 
	return ; 
 
}

Instruction pour la compilation sous Linux (ici 64bits) :
Code :
mex -I/usr/include -L/usr/lib/x86_64-linux-gnu -lSDL -lSDL_gfx affiche.c
ou plus simplement (avec les chemins par défaut) :
Code :
mex -lSDL -lSDL_gfx affiche.c
Je tiens à remercier Dut, LittleWhite et edgarjacobs pour leurs contributions.