Distortion.cpp
1 |
/*********************************************************************************** |
2 |
ImAnalyse : software in image processing and image analysis |
3 |
|
4 |
Copyright (C) 27 avril 2008 <Vincent MORARD> |
5 |
Version: 2.0 |
6 |
Contact: vincent<POINT>morard<AROBAS>cpe<POINT>fr |
7 |
Website: http://pistol.petesampras.free.fr |
8 |
|
9 |
This program is free software: you can redistribute it and/or modify |
10 |
it under the terms of the GNU General Public License as published by |
11 |
the Free Software Foundation, either version 3 of the License, or |
12 |
(at your option) any later version. |
13 |
|
14 |
This program is distributed in the hope that it will be useful, |
15 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 |
GNU General Public License for more details. |
18 |
|
19 |
You should have received a copy of the GNU General Public License |
20 |
along with this program. If not, see <http://www.gnu.org/licenses/ |
21 |
**********************************************************************************/ |
22 |
|
23 |
#include "CImage.h" |
24 |
|
25 |
#define Round(x) ((floor(x) + 0.5 > x)?(ceil(x)):(floor(x))) |
26 |
#define Square(a) (a*a) |
27 |
double Min(double A1,double A2, double A3, double A4) |
28 |
{ |
29 |
return min(A1,min(A2,min(A3,A4))); |
30 |
|
31 |
} |
32 |
double Max(double A1,double A2, double A3, double A4) |
33 |
{ |
34 |
return max(A1,max(A2,max(A3,A4))); |
35 |
|
36 |
} |
37 |
|
38 |
bool CImage::Resize(int newWidth,int newHeight,UCHAR *newucBits) |
39 |
{ |
40 |
//Desallocation |
41 |
DeleteObject(hBmp); |
42 |
hBmp=0; |
43 |
if(ucBits!=0){ |
44 |
FREEMEM(ucBits); |
45 |
ucBits=0; |
46 |
} |
47 |
|
48 |
|
49 |
//Nouvelles dimensions et attributs |
50 |
Width=newWidth; |
51 |
Height=newHeight; |
52 |
|
53 |
|
54 |
//Allocation |
55 |
ucBits = (UCHAR*)ALLOCMEM((Width*Height)*4); |
56 |
if(ucBits == 0) |
57 |
{ |
58 |
MessageBox(NULL," Resize : erreur fatale: allocation ucBits", |
59 |
NULL,MB_OK|MB_ICONWARNING); |
60 |
return 0; |
61 |
} |
62 |
|
63 |
if(newucBits == 0) //image noir |
64 |
memset(ucBits,0,(Width*Height)*4); |
65 |
else //On copie les données |
66 |
memcpy(ucBits,newucBits,(Width*Height)*4); |
67 |
|
68 |
//Création du bitmap |
69 |
hBmp=CreateBitmap(Width,Height,Planes,BitsPixel,ucBits) ; |
70 |
if(hBmp == 0) |
71 |
{ |
72 |
MessageBox(NULL," Resize : erreur fatale: allocation bmp", |
73 |
NULL,MB_OK|MB_ICONWARNING); |
74 |
return 0; |
75 |
} |
76 |
return 1; |
77 |
|
78 |
} |
79 |
|
80 |
|
81 |
|
82 |
bool CImage::Rotation(double Alpha,int Type,CImage *ImgDest) |
83 |
{ |
84 |
if(abs(Alpha-90) < 0.01) |
85 |
return Rotation_90(ImgDest); |
86 |
if(abs(Alpha-180) < 0.01) |
87 |
return Rotation_180(ImgDest); |
88 |
if(abs(Alpha-270) < 0.01) |
89 |
return Rotation_270(ImgDest); |
90 |
if(hBmp==0){ |
91 |
MessageBox(NULL," Rotation : L'image source est vide", |
92 |
NULL,MB_OK|MB_ICONWARNING); |
93 |
return 0; |
94 |
} |
95 |
|
96 |
if(Alpha == 0) |
97 |
{ |
98 |
if(ImgDest !=0 ) |
99 |
ImgDest->Copy(this); |
100 |
return 1; |
101 |
} |
102 |
|
103 |
if(ImgDest!=0 && ImgDest!=this) |
104 |
ImgDest->Copy(this); |
105 |
if(ImgDest==0) |
106 |
ImgDest=this; |
107 |
|
108 |
//Declaration des variables locales |
109 |
POINT_DOUBLE Pt[4]; |
110 |
double Xmax,Ymax,Xmin,Ymin; |
111 |
double TmpHeight,TmpWidth; |
112 |
UCHAR *TmpucBits; |
113 |
double i,j,k,l,ratioX,ratioY,P,Q; |
114 |
int x,y,x1,y1; |
115 |
|
116 |
//recupération des pixels |
117 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
118 |
|
119 |
//Calcul des nouvelles dimensions de l'image destination |
120 |
Pt[0].x = 0; |
121 |
Pt[0].y = 0; |
122 |
Alpha=PI*Alpha/180.0; |
123 |
|
124 |
Pt[1].x = Width * cos(Alpha) + 0 * sin(Alpha); |
125 |
Pt[1].y = Width * sin(Alpha) - 0 * cos(Alpha); |
126 |
|
127 |
Pt[2].x = Width * cos(Alpha) + Height * sin(Alpha); |
128 |
Pt[2].y = Width * sin(Alpha) - Height * cos(Alpha); |
129 |
|
130 |
Pt[3].x = 0 * cos(Alpha) + Height * sin(Alpha); |
131 |
Pt[3].y = 0 * sin(Alpha) - Height * cos(Alpha); |
132 |
|
133 |
|
134 |
Xmin = Min(Pt[0].x,Pt[1].x,Pt[2].x,Pt[3].x); |
135 |
Xmax = Max(Pt[0].x,Pt[1].x,Pt[2].x,Pt[3].x); |
136 |
Ymin = Min(Pt[0].y,Pt[1].y,Pt[2].y,Pt[3].y); |
137 |
Ymax = Max(Pt[0].y,Pt[1].y,Pt[2].y,Pt[3].y); |
138 |
|
139 |
|
140 |
TmpWidth = (Xmax-Xmin); |
141 |
TmpHeight = (Ymax-Ymin); |
142 |
if(TmpWidth<(int)TmpWidth+0.001) |
143 |
TmpWidth=(double)((int)TmpWidth); |
144 |
|
145 |
if(TmpHeight<(int)TmpHeight+0.001) |
146 |
TmpHeight=(double)((int)TmpHeight); |
147 |
|
148 |
TmpHeight=ceil(TmpHeight); |
149 |
TmpWidth=ceil(TmpWidth); |
150 |
//Allocation dynamique |
151 |
TmpucBits = (UCHAR*)ALLOCMEM((int)(TmpWidth*TmpHeight)*4); |
152 |
int lMath,kMath; |
153 |
double r,Theta,iMath,jMath; |
154 |
//rotation |
155 |
for(l=0;k,l<TmpHeight;l++) //pour tous les pixels de l'image dest |
156 |
{ |
157 |
for(k=0;k<TmpWidth;k++) |
158 |
{ |
159 |
lMath=(int)(TmpHeight-l-TmpHeight/2); |
160 |
kMath=(int)(k-TmpWidth/2); |
161 |
r=sqrt((double)(lMath*lMath+kMath*kMath)); |
162 |
|
163 |
if(kMath>0 && lMath>=0) |
164 |
Theta=atan((double)lMath/(double)kMath); |
165 |
else if(kMath>0 && lMath<0) |
166 |
Theta=atan((double)lMath/(double)kMath)+2*PI; |
167 |
else if(kMath<0) |
168 |
Theta=atan((double)lMath/(double)kMath)+PI; |
169 |
else if(kMath==0 && lMath>0) |
170 |
Theta=PI/2; |
171 |
else Theta=3*PI/2; |
172 |
|
173 |
Theta=Theta-Alpha; |
174 |
|
175 |
iMath=r*cos(Theta); |
176 |
jMath=r*sin(Theta); |
177 |
|
178 |
i=iMath+Width/2; |
179 |
j=Height-jMath-Height/2; |
180 |
|
181 |
if(i<(int)i+0.01) |
182 |
i=(int)i; |
183 |
if(j<(int)j+0.01) |
184 |
j=(int)j; |
185 |
//hors limite |
186 |
int Pos=(int)(4*(k+l*TmpWidth)); |
187 |
if(i < 0 || i>Width-1 || j<0 || j>Height-1) |
188 |
{ |
189 |
TmpucBits[Pos]=255; |
190 |
TmpucBits[Pos+1]=255; |
191 |
TmpucBits[Pos+2]=255; |
192 |
} |
193 |
else if(Type == 1) //Nearest |
194 |
{ |
195 |
x=(int)Round(i); |
196 |
y=(int)Round(j); |
197 |
TmpucBits[Pos]=(UCHAR)this->GetPixel(x,y,BLUE); |
198 |
TmpucBits[Pos+1]=(UCHAR)this->GetPixel(x,y,GREEN); |
199 |
TmpucBits[Pos+2]=(UCHAR)this->GetPixel(x,y,RED); |
200 |
} |
201 |
else //Interpolation bilineaire |
202 |
{ |
203 |
x=(int)ceil(i); |
204 |
y=(int)ceil(j); |
205 |
x1=(int)floor(i); |
206 |
y1=(int)floor(j); |
207 |
ratioX=(double)(i-x1); |
208 |
ratioY=(double)(j-y1); |
209 |
|
210 |
P=ratioX*(double)this->GetPixel((int)x,(int)y1,BLUE)+(1-ratioX)*(double)this->GetPixel((int)x1,(int)y1,BLUE); |
211 |
Q=ratioX*(double)this->GetPixel((int)x,(int)y,BLUE)+(1-ratioX)*(double)this->GetPixel((int)x1,(int)y,BLUE); |
212 |
TmpucBits[Pos]=(int)(Q *ratioY + P*(1- ratioY)); |
213 |
|
214 |
P=ratioX*(double)this->GetPixel((int)x,(int)y1,GREEN)+(1-ratioX)*(double)this->GetPixel((int)x1,(int)y1,GREEN); |
215 |
Q=ratioX*(double)this->GetPixel((int)x,(int)y,GREEN)+(1-ratioX)*(double)this->GetPixel((int)x1,(int)y,GREEN); |
216 |
TmpucBits[Pos+1]=(int)(Q *ratioY + P*(1- ratioY)); |
217 |
|
218 |
P=ratioX*(double)this->GetPixel((int)x,(int)y1,RED)+(1-ratioX)*(double)this->GetPixel((int)x1,(int)y1,RED); |
219 |
Q=ratioX*(double)this->GetPixel((int)x,(int)y,RED)+(1-ratioX)*(double)this->GetPixel((int)x1,(int)y,RED); |
220 |
TmpucBits[Pos+2]=(int)(Q *ratioY + P*(1- ratioY)); |
221 |
} |
222 |
} |
223 |
|
224 |
} |
225 |
if(!ImgDest->Resize((int)TmpWidth,(int)TmpHeight,TmpucBits)){ |
226 |
FREEMEM(TmpucBits); |
227 |
return 0; |
228 |
} |
229 |
|
230 |
FREEMEM(TmpucBits); |
231 |
return 1; |
232 |
} |
233 |
|
234 |
|
235 |
bool CImage::Stretch(int PourcentageX,int PourcentageY,int Type, CImage *ImgDest) |
236 |
{ |
237 |
|
238 |
if(hBmp==0){ |
239 |
MessageBox(NULL," Strech : L'image source est vide", |
240 |
NULL,MB_OK|MB_ICONWARNING); |
241 |
return 0; |
242 |
} |
243 |
|
244 |
if(PourcentageX<=0 || PourcentageX>500){ |
245 |
MessageBox(NULL," Strech : Le pourcentage doit etre compris entre 0 et 500", |
246 |
NULL,MB_OK|MB_ICONWARNING); |
247 |
return 0; |
248 |
} |
249 |
if(PourcentageY<=0 || PourcentageY>500){ |
250 |
MessageBox(NULL," Strech : Le pourcentage doit etre compris entre 0 et 500", |
251 |
NULL,MB_OK|MB_ICONWARNING); |
252 |
return 0; |
253 |
} |
254 |
|
255 |
|
256 |
if(ImgDest!=0 && ImgDest!=this) |
257 |
ImgDest->Copy(this); |
258 |
if(ImgDest==0) |
259 |
ImgDest=this; |
260 |
|
261 |
|
262 |
if(PourcentageX == 100 && PourcentageY == 100){ |
263 |
SetBitmapBits (ImgDest->hBmp,(Width*Height)*4,ImgDest->ucBits); |
264 |
return 1; //aucun traitement a faire |
265 |
} |
266 |
|
267 |
|
268 |
GetBitmapBits (hBmp,(Width*Height)*4,ucBits); |
269 |
|
270 |
int TmpWidth,TmpHeight; |
271 |
UCHAR *TmpucBits=0; |
272 |
double k,l,i,j,ratioX,ratioY,P,Q,ReductionX,ReductionY; |
273 |
int x,y,x1,y1,Pos; |
274 |
|
275 |
|
276 |
|
277 |
TmpWidth =(int)floor((double)(Width*PourcentageX/100)); |
278 |
TmpHeight=(int)floor((double)(Height*PourcentageY/100)); |
279 |
|
280 |
ReductionX=(double)(Width/(double)TmpWidth); |
281 |
ReductionY=(double)(Height/(double)TmpHeight); |
282 |
|
283 |
//Allocation dynamique |
284 |
TmpucBits = (UCHAR*)ALLOCMEM((TmpWidth*TmpHeight)*4); |
285 |
|
286 |
if(TmpucBits==0){ |
287 |
MessageBox(NULL," Strech :Erreur allocation: Fin du traitement", |
288 |
NULL,MB_OK|MB_ICONWARNING); |
289 |
return 0; |
290 |
|
291 |
} |
292 |
|
293 |
for(l=0;k,l<TmpHeight;l++) //pour tous les pixels de l'image dest |
294 |
{ |
295 |
for(k=0;k<TmpWidth;k++) |
296 |
{ |
297 |
i=k*ReductionX; |
298 |
j=l*ReductionY; |
299 |
|
300 |
Pos=(int)(4*(k+l*TmpWidth)); |
301 |
|
302 |
//hors limite ...useless??? |
303 |
if(i < 0 || i>Width-1 || j<0 || j>Height-1) |
304 |
{ |
305 |
TmpucBits[Pos]=0; |
306 |
TmpucBits[Pos+1]=255; |
307 |
TmpucBits[Pos+2]=255; |
308 |
} |
309 |
else if(Type == 1) //Nearest |
310 |
{ |
311 |
x=(int)Round(i); |
312 |
y=(int)Round(j); |
313 |
TmpucBits[Pos]=(UCHAR)this->GetPixel(x,y,BLUE); |
314 |
TmpucBits[Pos+1]=(UCHAR)this->GetPixel(x,y,GREEN); |
315 |
TmpucBits[Pos+2]=(UCHAR)this->GetPixel(x,y,RED); |
316 |
} |
317 |
else //Interpolation bilineaire |
318 |
{ |
319 |
x=(int)ceil(i); |
320 |
y=(int)ceil(j); |
321 |
x1=(int)floor(i); |
322 |
y1=(int)floor(j); |
323 |
ratioX=(double)(i-x1); |
324 |
ratioY=(double)(j-y1); |
325 |
|
326 |
P=ratioX*(double)this->GetPixel(x,y1,BLUE)+(1-ratioX)*(double)this->GetPixel(x1,y1,BLUE); |
327 |
Q=ratioX*(double)this->GetPixel(x,y,BLUE)+(1-ratioX)*(double)this->GetPixel(x1,y,BLUE); |
328 |
TmpucBits[Pos]=(int)(Q *ratioY + P*(1- ratioY)); |
329 |
|
330 |
P=ratioX*(double)this->GetPixel(x,y1,GREEN)+(1-ratioX)*(double)this->GetPixel(x1,y1,GREEN); |
331 |
Q=ratioX*(double)this->GetPixel(x,y,GREEN)+(1-ratioX)*(double)this->GetPixel(x1,y,GREEN); |
332 |
TmpucBits[Pos+1]=(int)(Q *ratioY + P*(1- ratioY)); |
333 |
|
334 |
P=ratioX*(double)this->GetPixel(x,y1,RED)+(1-ratioX)*(double)this->GetPixel(x1,y1,RED); |
335 |
Q=ratioX*(double)this->GetPixel(x,y,RED)+(1-ratioX)*(double)this->GetPixel(x1,y,RED); |
336 |
TmpucBits[Pos+2]=(int)(Q *ratioY + P*(1- ratioY)); |
337 |
} |
338 |
} |
339 |
} |
340 |
if(ImgDest->Resize(TmpWidth,TmpHeight,TmpucBits)){ |
341 |
FREEMEM(TmpucBits); |
342 |
return 0; |
343 |
} |
344 |
|
345 |
SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); |
346 |
FREEMEM(TmpucBits); |
347 |
return 1; |
348 |
} |
349 |
|
350 |
|
351 |
bool CImage::Flip(bool Hori,CImage *ImgDest) |
352 |
{ |
353 |
if(hBmp==0){ |
354 |
MessageBox(NULL," Flip : L'image source est vide", |
355 |
NULL,MB_OK|MB_ICONWARNING); |
356 |
return 0; |
357 |
} |
358 |
|
359 |
|
360 |
if(ImgDest!=0 && ImgDest!=this) |
361 |
ImgDest->Copy(this); |
362 |
if(ImgDest==0) |
363 |
ImgDest=this; |
364 |
|
365 |
int i,j,Pos; |
366 |
CImage ImgTmp; |
367 |
ImgTmp.Copy(this); |
368 |
|
369 |
//recupération des pixels |
370 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
371 |
|
372 |
|
373 |
|
374 |
//flip |
375 |
if(Hori) |
376 |
{ |
377 |
for(j=0;j<Height;j++) |
378 |
for(i=0;i<Width;i++) |
379 |
{ |
380 |
Pos=4*(i+j*Width); |
381 |
ImgTmp.SetPixel(Width-1-i,j,ucBits[Pos+2],ucBits[Pos+1],ucBits[Pos]); |
382 |
} |
383 |
} |
384 |
else |
385 |
{ |
386 |
for(j=0;j<Height;j++) |
387 |
for(i=0;i<Width;i++) |
388 |
{ |
389 |
Pos=4*(i+j*Width); |
390 |
ImgTmp.SetPixel(i,Height-1-j,ucBits[Pos+2],ucBits[Pos+1],ucBits[Pos]); |
391 |
} |
392 |
} |
393 |
|
394 |
ImgDest->Copy(&ImgTmp); |
395 |
SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); |
396 |
return 1; |
397 |
} |
398 |
|
399 |
|
400 |
|
401 |
bool CImage::Rotation_90(CImage *ImgDest) |
402 |
{ |
403 |
|
404 |
if(hBmp==0){ |
405 |
MessageBox(NULL," Rotation_90 : L'image source est vide", |
406 |
NULL,MB_OK|MB_ICONWARNING); |
407 |
return 0; |
408 |
} |
409 |
|
410 |
if(ImgDest!=0 && ImgDest!=this) |
411 |
ImgDest->Copy(this); |
412 |
if(ImgDest==0) |
413 |
ImgDest=this; |
414 |
|
415 |
//Declaration des variables locales |
416 |
|
417 |
|
418 |
int TmpHeight,TmpWidth; |
419 |
UCHAR *TmpucBits=0; |
420 |
int i,j,k,l; |
421 |
|
422 |
|
423 |
//recupération des pixels |
424 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
425 |
|
426 |
|
427 |
TmpWidth = Height; |
428 |
TmpHeight = Width; |
429 |
|
430 |
//Allocation dynamique |
431 |
TmpucBits = (UCHAR*)ALLOCMEM((TmpWidth*TmpHeight)*4); |
432 |
|
433 |
if(ucBits==0){ |
434 |
MessageBox(NULL," Rotation_90 :Erreur allocation traitement annule", |
435 |
NULL,MB_OK|MB_ICONWARNING); |
436 |
return 0; |
437 |
|
438 |
} |
439 |
|
440 |
|
441 |
for(l=0;k,l<TmpHeight;l++) //pour tous les pixels de l'image dest |
442 |
{ |
443 |
for(k=0;k<TmpWidth;k++) |
444 |
{ |
445 |
//Determination des coordonnees dans l'image initial; |
446 |
i = Width-1-l ; |
447 |
j = k; |
448 |
|
449 |
int Pos=4*(k+l*TmpWidth); |
450 |
|
451 |
TmpucBits[Pos]=(UCHAR)this->GetPixel(i,j,BLUE); |
452 |
TmpucBits[Pos+1]=(UCHAR)this->GetPixel(i,j,GREEN); |
453 |
TmpucBits[Pos+2]=(UCHAR)this->GetPixel(i,j,RED); |
454 |
} |
455 |
|
456 |
} |
457 |
if(ImgDest->Resize(TmpWidth,TmpHeight,TmpucBits)){ |
458 |
FREEMEM(TmpucBits); |
459 |
return 0; |
460 |
} |
461 |
|
462 |
FREEMEM(TmpucBits); |
463 |
SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); |
464 |
return 1; |
465 |
} |
466 |
|
467 |
bool CImage::Rotation_270(CImage *ImgDest) |
468 |
{ |
469 |
|
470 |
if(hBmp==0){ |
471 |
MessageBox(NULL," Rotation_270 : L'image source est vide", |
472 |
NULL,MB_OK|MB_ICONWARNING); |
473 |
return 0; |
474 |
} |
475 |
|
476 |
if(ImgDest!=0 && ImgDest!=this) |
477 |
ImgDest->Copy(this); |
478 |
if(ImgDest==0) |
479 |
ImgDest=this; |
480 |
|
481 |
//Declaration des variables locales |
482 |
int TmpHeight,TmpWidth; |
483 |
UCHAR *TmpucBits=0; |
484 |
int i,j,k,l; |
485 |
|
486 |
//recupération des pixels |
487 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
488 |
|
489 |
|
490 |
TmpWidth = Height; |
491 |
TmpHeight = Width; |
492 |
|
493 |
//Allocation dynamique |
494 |
TmpucBits = (UCHAR*)ALLOCMEM((TmpWidth*TmpHeight)*4); |
495 |
|
496 |
if(ucBits==0){ |
497 |
MessageBox(NULL," Rotation_270 :Erreur allocation traitement annule", |
498 |
NULL,MB_OK|MB_ICONWARNING); |
499 |
return 0; |
500 |
|
501 |
} |
502 |
|
503 |
|
504 |
for(l=0;k,l<TmpHeight;l++) //pour tous les pixels de l'image dest |
505 |
{ |
506 |
for(k=0;k<TmpWidth;k++) |
507 |
{ |
508 |
//Determination des coordonnees dans l'image initial; |
509 |
i = l ; |
510 |
j = Height-1-k; |
511 |
|
512 |
int Pos=4*(k+l*TmpWidth); |
513 |
|
514 |
TmpucBits[Pos]=(UCHAR)this->GetPixel(i,j,BLUE); |
515 |
TmpucBits[Pos+1]=(UCHAR)this->GetPixel(i,j,GREEN); |
516 |
TmpucBits[Pos+2]=(UCHAR)this->GetPixel(i,j,RED); |
517 |
} |
518 |
|
519 |
} |
520 |
if(ImgDest->Resize(TmpWidth,TmpHeight,TmpucBits)){ |
521 |
FREEMEM(TmpucBits); |
522 |
return 0; |
523 |
} |
524 |
|
525 |
FREEMEM(TmpucBits); |
526 |
SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); |
527 |
return 1; |
528 |
} |
529 |
|
530 |
|
531 |
bool CImage::Rotation_180(CImage *ImgDest) |
532 |
{ |
533 |
|
534 |
if(hBmp==0){ |
535 |
MessageBox(NULL," Rotation_180 : L'image source est vide", |
536 |
NULL,MB_OK|MB_ICONWARNING); |
537 |
return 0; |
538 |
} |
539 |
|
540 |
if(ImgDest!=0 && ImgDest!=this) |
541 |
ImgDest->Copy(this); |
542 |
if(ImgDest==0) |
543 |
ImgDest=this; |
544 |
|
545 |
//Declaration des variables locales |
546 |
|
547 |
UCHAR *TmpucBits=0; |
548 |
int i,j,k,l; |
549 |
|
550 |
//recupération des pixels |
551 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
552 |
|
553 |
|
554 |
//Allocation dynamique |
555 |
TmpucBits = (UCHAR*)ALLOCMEM((Width*Height)*4); |
556 |
|
557 |
if(ucBits==0){ |
558 |
MessageBox(NULL," Rotation_180 :Erreur allocation traitement annule", |
559 |
NULL,MB_OK|MB_ICONWARNING); |
560 |
return 0; |
561 |
|
562 |
} |
563 |
|
564 |
|
565 |
for(l=0;k,l<Height;l++) //pour tous les pixels de l'image dest |
566 |
{ |
567 |
for(k=0;k<Width;k++) |
568 |
{ |
569 |
//Determination des coordonnees dans l'image initial; |
570 |
|
571 |
i = Width-1-k ; |
572 |
j = Height-1-l; |
573 |
|
574 |
|
575 |
int Pos=4*(k+l*Width); |
576 |
|
577 |
TmpucBits[Pos]=(UCHAR)this->GetPixel(i,j,BLUE); |
578 |
TmpucBits[Pos+1]=(UCHAR)this->GetPixel(i,j,GREEN); |
579 |
TmpucBits[Pos+2]=(UCHAR)this->GetPixel(i,j,RED); |
580 |
} |
581 |
|
582 |
} |
583 |
|
584 |
memcpy(ImgDest->ucBits,TmpucBits,Width*Height*4); |
585 |
SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); |
586 |
FREEMEM(TmpucBits); |
587 |
return 1; |
588 |
} |
589 |
|
590 |
|
591 |
|
592 |
bool CImage::InvertColor(CImage *ImgDest) |
593 |
{ |
594 |
if(hBmp==0){ |
595 |
MessageBox(NULL," InvertColor : L'image source est vide", |
596 |
NULL,MB_OK|MB_ICONWARNING); |
597 |
return 0; |
598 |
} |
599 |
|
600 |
if(ImgDest!=0 && ImgDest!=this) |
601 |
ImgDest->Copy(this); |
602 |
if(ImgDest==0) |
603 |
ImgDest=this; |
604 |
|
605 |
//recupération des pixels |
606 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
607 |
int i; |
608 |
|
609 |
for(i=0;i<4*Height*Width;i+=4) |
610 |
{ |
611 |
ImgDest->ucBits[i]=255-ucBits[i]; |
612 |
ImgDest->ucBits[i+1]=255-ucBits[i+1]; |
613 |
ImgDest->ucBits[i+2]=255-ucBits[i+2]; |
614 |
|
615 |
} |
616 |
SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); |
617 |
return 1; |
618 |
|
619 |
} |
620 |
|
621 |
|
622 |
|
623 |
bool CImage::Statistique_Mean(int Type,double *mR,double *mG,double *mB,RECT *Zone) |
624 |
{ |
625 |
if(hBmp==0){ |
626 |
MessageBox(NULL," Statistique_Mean : L'image source est vide", |
627 |
NULL,MB_OK|MB_ICONWARNING); |
628 |
return 0; |
629 |
} |
630 |
|
631 |
if(mR == 0 && Type == GRAY){ |
632 |
MessageBox(NULL," Statistique_Mean : Parametre 2 (std_RED <==>GRAY) OBLIGATOIRE", |
633 |
NULL,MB_OK|MB_ICONWARNING); |
634 |
return 0; |
635 |
} |
636 |
if(mR == 0 && Type == RED){ |
637 |
MessageBox(NULL," Statistique_Mean : Parametre 2 (std_RED) OBLIGATOIRE", |
638 |
NULL,MB_OK|MB_ICONWARNING); |
639 |
return 0; |
640 |
} |
641 |
if(mG == 0 && Type == GREEN){ |
642 |
MessageBox(NULL," Statistique_Mean : Parametre 3 (std_GREEN) OBLIGATOIRE", |
643 |
NULL,MB_OK|MB_ICONWARNING); |
644 |
return 0; |
645 |
} |
646 |
if(mB == 0 && Type == BLUE){ |
647 |
MessageBox(NULL," Statistique_Mean : Parametre 4 (std_BLUE) OBLIGATOIRE", |
648 |
NULL,MB_OK|MB_ICONWARNING); |
649 |
return 0; |
650 |
} |
651 |
if((mR == 0 || mG == 0 || mB == 0 ) && Type == RGBi){ |
652 |
MessageBox(NULL," Statistique_Mean : Parametre 2,3,4 OBLIGATOIRES", |
653 |
NULL,MB_OK|MB_ICONWARNING); |
654 |
return 0; |
655 |
} |
656 |
RECT Rect; |
657 |
if(Zone==0){ |
658 |
Rect.top=0; |
659 |
Rect.left=0; |
660 |
Rect.right=Width-1; |
661 |
Rect.bottom=Height-1; |
662 |
} |
663 |
else{ |
664 |
Rect.top=Zone->top; |
665 |
Rect.left=Zone->left; |
666 |
Rect.right=Zone->right; |
667 |
Rect.bottom=Zone->bottom; |
668 |
} |
669 |
if(Rect.top<0 || Rect.left<0 || Rect.bottom>=Height || Rect.right>=Width){ |
670 |
MessageBox(NULL," Statistique_Mean : Zone specifie a l'exterieur de l'image", |
671 |
NULL,MB_OK|MB_ICONWARNING); |
672 |
return 0; |
673 |
} |
674 |
|
675 |
//recupération des pixels |
676 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
677 |
|
678 |
//initialisation |
679 |
double Nb=0; |
680 |
if(mR)*mR=0; |
681 |
if(mG)*mG=0; |
682 |
if(mB)*mB=0; |
683 |
|
684 |
int i,j,Pos; |
685 |
|
686 |
for(i=Rect.left;i<=Rect.right;i++) |
687 |
{ |
688 |
for(j=Rect.top;j<=Rect.bottom;j++) |
689 |
{ |
690 |
Pos=4*(i+j*Width); |
691 |
switch(Type) |
692 |
{ |
693 |
case BLUE : *mB+=ucBits[Pos] ;break; |
694 |
case GREEN: *mG+=ucBits[Pos+1];break; |
695 |
case RED : *mR+=ucBits[Pos+2];break; |
696 |
case RGBi : *mB+=ucBits[Pos]; |
697 |
*mG+=ucBits[Pos+1]; |
698 |
*mR+=ucBits[Pos+2];break; |
699 |
case BIN: |
700 |
case GRAY : *mR+=((ucBits[Pos]+ucBits[Pos+1]+ucBits[Pos+2])/3); |
701 |
} |
702 |
Nb++; |
703 |
} |
704 |
} |
705 |
if(Nb==0) |
706 |
return 0; |
707 |
|
708 |
switch(Type) |
709 |
{ |
710 |
case BLUE : *mB/=Nb;break; |
711 |
case GREEN: *mG/=Nb;break; |
712 |
case BIN: |
713 |
case GRAY : |
714 |
case RED : *mR/=Nb;break; |
715 |
case RGBi : *mB/=Nb; |
716 |
*mG/=Nb; |
717 |
*mR/=Nb;break; |
718 |
|
719 |
|
720 |
} |
721 |
return 1; |
722 |
} |
723 |
|
724 |
bool CImage::Statistique_STD(int Type,double *std_RED,double *std_GREEN,double *std_BLUE,RECT *Zone) |
725 |
{ |
726 |
|
727 |
if(hBmp==0){ |
728 |
MessageBox(NULL," Statistique_STD : L'image source est vide", |
729 |
NULL,MB_OK|MB_ICONWARNING); |
730 |
return 0; |
731 |
} |
732 |
|
733 |
if(std_RED == 0 && Type == GRAY){ |
734 |
MessageBox(NULL," Statistique_STD : Parametre 2 (std_RED <==>GRAY) OBLIGATOIRE", |
735 |
NULL,MB_OK|MB_ICONWARNING); |
736 |
return 0; |
737 |
} |
738 |
if(std_RED == 0 && Type == RED){ |
739 |
MessageBox(NULL," Statistique_STD : Parametre 2 (std_RED) OBLIGATOIRE", |
740 |
NULL,MB_OK|MB_ICONWARNING); |
741 |
return 0; |
742 |
} |
743 |
if(std_GREEN == 0 && Type == GREEN){ |
744 |
MessageBox(NULL," Statistique_STD : Parametre 3 (std_GREEN) OBLIGATOIRE", |
745 |
NULL,MB_OK|MB_ICONWARNING); |
746 |
return 0; |
747 |
} |
748 |
if(std_BLUE == 0 && Type == BLUE){ |
749 |
MessageBox(NULL," Statistique_STD : Parametre 4 (std_BLUE) OBLIGATOIRE", |
750 |
NULL,MB_OK|MB_ICONWARNING); |
751 |
return 0; |
752 |
} |
753 |
if((std_RED == 0 || std_GREEN == 0 || std_BLUE == 0 ) && Type == RGBi){ |
754 |
MessageBox(NULL," Statistique_STD : Parametre 2,3,4 OBLIGATOIRES", |
755 |
NULL,MB_OK|MB_ICONWARNING); |
756 |
return 0; |
757 |
} |
758 |
|
759 |
RECT Rect; |
760 |
if(Zone==0){ |
761 |
Rect.top=0; |
762 |
Rect.left=0; |
763 |
Rect.right=Width-1; |
764 |
Rect.bottom=Height-1; |
765 |
} |
766 |
else{ |
767 |
Rect.top=Zone->top; |
768 |
Rect.left=Zone->left; |
769 |
Rect.right=Zone->right; |
770 |
Rect.bottom=Zone->bottom; |
771 |
} |
772 |
if(Rect.top<0 || Rect.left<0 || Rect.bottom>=Height || Rect.right>=Width){ |
773 |
MessageBox(NULL," Statistique_Std : Zone specifie a l'exterieur de l'image", |
774 |
NULL,MB_OK|MB_ICONWARNING); |
775 |
return 0; |
776 |
} |
777 |
|
778 |
//recupération des pixels |
779 |
GetBitmapBits(hBmp,Width*Height*4,ucBits); |
780 |
|
781 |
//initialisation |
782 |
double NB=0; |
783 |
double mR,mG,mB; |
784 |
|
785 |
if(!Statistique_Mean(Type,&mR,&mG,&mB,&Rect)){ |
786 |
MessageBox(NULL," Statistique_STD :Erreur pendant la lecture des valeurs moyennes", |
787 |
NULL,MB_OK|MB_ICONWARNING); |
788 |
return 0; |
789 |
} |
790 |
|
791 |
if(std_RED)*std_RED=0; |
792 |
if(std_GREEN)*std_GREEN=0; |
793 |
if(std_BLUE)*std_BLUE=0; |
794 |
|
795 |
int i,j,Pos,Nb=0; |
796 |
|
797 |
for(i=Rect.left;i<=Rect.right;i++) |
798 |
{ |
799 |
for(j=Rect.top;j<=Rect.bottom;j++) |
800 |
{ |
801 |
Pos=4*(i+j*Width); |
802 |
switch(Type) |
803 |
{ |
804 |
case RED :*std_RED +=((ucBits[Pos+2]-mR)*(ucBits[Pos+2]-mR));break; |
805 |
case GREEN:*std_GREEN+=((ucBits[Pos+1]-mG)*(ucBits[Pos+1]-mG));break; |
806 |
case BLUE :*std_BLUE +=((ucBits[Pos] -mB)*(ucBits[Pos] -mB));break; |
807 |
|
808 |
case RGBi :*std_GREEN+=((ucBits[Pos+1]-mG)*(ucBits[Pos+1]-mG)); |
809 |
*std_RED +=((ucBits[Pos+2]-mR)*(ucBits[Pos+2]-mR)); |
810 |
*std_BLUE +=((ucBits[Pos]-mB)*(ucBits[Pos]-mB)) ;break; |
811 |
case BIN: |
812 |
case GRAY :*std_RED +=((ucBits[Pos+2]+ucBits[Pos+1]+ucBits[Pos])/3-mR)*((ucBits[Pos+2]+ucBits[Pos+1]+ucBits[Pos])/3-mR);break; |
813 |
} |
814 |
Nb++; |
815 |
} |
816 |
} |
817 |
|
818 |
if(Nb==0) |
819 |
return 0; |
820 |
|
821 |
switch(Type) |
822 |
{ |
823 |
case BLUE : *std_BLUE =sqrt(*std_BLUE/Nb) ;break; |
824 |
case GREEN : *std_GREEN=sqrt(*std_GREEN/Nb);break; |
825 |
case BIN: |
826 |
case GRAY : |
827 |
case RED : *std_RED =sqrt(*std_RED/Nb) ;break; |
828 |
case RGBi : *std_BLUE =sqrt(*std_BLUE/Nb) ; |
829 |
*std_GREEN=sqrt(*std_GREEN/Nb); |
830 |
*std_RED =sqrt(*std_RED/Nb) ;break; |
831 |
|
832 |
|
833 |
} |
834 |
|
835 |
return 1; |
836 |
} |
837 |
|
838 |
|
839 |
|
lien1 lien2 lien3