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