Back to index

php5  5.3.10
gd_filter.c
Go to the documentation of this file.
00001 #if HAVE_GD_BUNDLED
00002 # include "gd.h"
00003 #else
00004 # include <gd.h>
00005 #endif
00006 
00007 #include "gd_intern.h"
00008 
00009 /* Filters function added on 2003/12
00010  * by Pierre-Alain Joye (pierre@php.net)
00011  **/
00012 /* Begin filters function */
00013 #define GET_PIXEL_FUNCTION(src)(src->trueColor?gdImageGetTrueColorPixel:gdImageGetPixel)
00014 
00015 /* invert src image */
00016 int gdImageNegate(gdImagePtr src)
00017 {
00018        int x, y;
00019        int r,g,b,a;
00020        int new_pxl, pxl;
00021        typedef int (*FuncPtr)(gdImagePtr, int, int);
00022        FuncPtr f;
00023 
00024        if (src==NULL) {
00025               return 0;
00026        }
00027 
00028        f = GET_PIXEL_FUNCTION(src);
00029 
00030        for (y=0; y<src->sy; ++y) {
00031               for (x=0; x<src->sx; ++x) {
00032                      pxl = f (src, x, y);
00033                      r = gdImageRed(src, pxl);
00034                      g = gdImageGreen(src, pxl);
00035                      b = gdImageBlue(src, pxl);
00036                      a = gdImageAlpha(src, pxl);
00037 
00038                      new_pxl = gdImageColorAllocateAlpha(src, 255-r, 255-g, 255-b, a);
00039                      if (new_pxl == -1) {
00040                             new_pxl = gdImageColorClosestAlpha(src, 255-r, 255-g, 255-b, a);
00041                      }
00042                      gdImageSetPixel (src, x, y, new_pxl);
00043               }
00044        }
00045        return 1;
00046 }
00047 
00048 /* Convert the image src to a grayscale image */
00049 int gdImageGrayScale(gdImagePtr src)
00050 {
00051        int x, y;
00052        int r,g,b,a;
00053        int new_pxl, pxl;
00054        typedef int (*FuncPtr)(gdImagePtr, int, int);
00055        FuncPtr f;
00056        f = GET_PIXEL_FUNCTION(src);
00057 
00058        if (src==NULL) {
00059               return 0;
00060        }
00061 
00062        for (y=0; y<src->sy; ++y) {
00063               for (x=0; x<src->sx; ++x) {
00064                      pxl = f (src, x, y);
00065                      r = gdImageRed(src, pxl);
00066                      g = gdImageGreen(src, pxl);
00067                      b = gdImageBlue(src, pxl);
00068                      a = gdImageAlpha(src, pxl);
00069                      r = g = b = (int) (.299 * r + .587 * g + .114 * b);
00070 
00071                      new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
00072                      if (new_pxl == -1) {
00073                             new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
00074                      }
00075                      gdImageSetPixel (src, x, y, new_pxl);
00076               }
00077        }
00078        return 1;
00079 }
00080 
00081 /* Set the brightness level <level> for the image src */
00082 int gdImageBrightness(gdImagePtr src, int brightness)
00083 {
00084        int x, y;
00085        int r,g,b,a;
00086        int new_pxl, pxl;
00087        typedef int (*FuncPtr)(gdImagePtr, int, int);
00088        FuncPtr f;
00089        f = GET_PIXEL_FUNCTION(src);
00090 
00091        if (src==NULL || (brightness < -255 || brightness>255)) {
00092               return 0;
00093        }
00094 
00095        if (brightness==0) {
00096               return 1;
00097        }
00098 
00099        for (y=0; y<src->sy; ++y) {
00100               for (x=0; x<src->sx; ++x) {
00101                      pxl = f (src, x, y);
00102 
00103                      r = gdImageRed(src, pxl);
00104                      g = gdImageGreen(src, pxl);
00105                      b = gdImageBlue(src, pxl);
00106                      a = gdImageAlpha(src, pxl);
00107 
00108                      r = r + brightness;
00109                      g = g + brightness;
00110                      b = b + brightness;
00111 
00112                      r = (r > 255)? 255 : ((r < 0)? 0:r);
00113                      g = (g > 255)? 255 : ((g < 0)? 0:g);
00114                      b = (b > 255)? 255 : ((b < 0)? 0:b);
00115 
00116                      new_pxl = gdImageColorAllocateAlpha(src, (int)r, (int)g, (int)b, a);
00117                      if (new_pxl == -1) {
00118                             new_pxl = gdImageColorClosestAlpha(src, (int)r, (int)g, (int)b, a);
00119                      }
00120                      gdImageSetPixel (src, x, y, new_pxl);
00121               }
00122        }
00123        return 1;
00124 }
00125 
00126 
00127 int gdImageContrast(gdImagePtr src, double contrast)
00128 {
00129        int x, y;
00130        int r,g,b,a;
00131        double rf,gf,bf;
00132        int new_pxl, pxl;
00133        typedef int (*FuncPtr)(gdImagePtr, int, int);
00134 
00135        FuncPtr f;
00136        f = GET_PIXEL_FUNCTION(src);
00137 
00138        if (src==NULL) {
00139               return 0;
00140        }
00141 
00142        contrast = (double)(100.0-contrast)/100.0;
00143        contrast = contrast*contrast;
00144 
00145        for (y=0; y<src->sy; ++y) {
00146               for (x=0; x<src->sx; ++x) {
00147                      pxl = f(src, x, y);
00148 
00149                      r = gdImageRed(src, pxl);
00150                      g = gdImageGreen(src, pxl);
00151                      b = gdImageBlue(src, pxl);
00152                      a = gdImageAlpha(src, pxl);
00153 
00154                      rf = (double)r/255.0;
00155                      rf = rf-0.5;
00156                      rf = rf*contrast;
00157                      rf = rf+0.5;
00158                      rf = rf*255.0;
00159 
00160                      bf = (double)b/255.0;
00161                      bf = bf-0.5;
00162                      bf = bf*contrast;
00163                      bf = bf+0.5;
00164                      bf = bf*255.0;
00165 
00166                      gf = (double)g/255.0;
00167                      gf = gf-0.5;
00168                      gf = gf*contrast;
00169                      gf = gf+0.5;
00170                      gf = gf*255.0;
00171 
00172                      rf = (rf > 255.0)? 255.0 : ((rf < 0.0)? 0.0:rf);
00173                      gf = (gf > 255.0)? 255.0 : ((gf < 0.0)? 0.0:gf);
00174                      bf = (bf > 255.0)? 255.0 : ((bf < 0.0)? 0.0:bf);
00175 
00176                      new_pxl = gdImageColorAllocateAlpha(src, (int)rf, (int)gf, (int)bf, a);
00177                      if (new_pxl == -1) {
00178                             new_pxl = gdImageColorClosestAlpha(src, (int)rf, (int)gf, (int)bf, a);
00179                      }
00180                      gdImageSetPixel (src, x, y, new_pxl);
00181               }
00182        }
00183        return 1;
00184 }
00185 
00186 
00187 int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha)
00188 {
00189        int x, y;
00190        int new_pxl, pxl;
00191        typedef int (*FuncPtr)(gdImagePtr, int, int);
00192        FuncPtr f;
00193 
00194        if (src == NULL) {
00195               return 0;
00196        }
00197 
00198        f = GET_PIXEL_FUNCTION(src);
00199 
00200        for (y=0; y<src->sy; ++y) {
00201               for (x=0; x<src->sx; ++x) {
00202                      int r,g,b,a;
00203 
00204                      pxl = f(src, x, y);
00205                      r = gdImageRed(src, pxl);
00206                      g = gdImageGreen(src, pxl);
00207                      b = gdImageBlue(src, pxl);
00208                      a = gdImageAlpha(src, pxl);
00209 
00210                      r = r + red;
00211                      g = g + green;
00212                      b = b + blue;
00213                      a = a + alpha;
00214 
00215                      r = (r > 255)? 255 : ((r < 0)? 0 : r);
00216                      g = (g > 255)? 255 : ((g < 0)? 0 : g);
00217                      b = (b > 255)? 255 : ((b < 0)? 0 : b);
00218                      a = (a > 127)? 127 : ((a < 0)? 0 : a);
00219 
00220                      new_pxl = gdImageColorAllocateAlpha(src, r, g, b, a);
00221                      if (new_pxl == -1) {
00222                             new_pxl = gdImageColorClosestAlpha(src, r, g, b, a);
00223                      }
00224                      gdImageSetPixel (src, x, y, new_pxl);
00225               }
00226        }
00227        return 1;
00228 }
00229 
00230 int gdImageConvolution(gdImagePtr src, float filter[3][3], float filter_div, float offset)
00231 {
00232        int         x, y, i, j, new_a;
00233        float       new_r, new_g, new_b;
00234        int         new_pxl, pxl=0;
00235        gdImagePtr  srcback;
00236        typedef int (*FuncPtr)(gdImagePtr, int, int);
00237        FuncPtr f;
00238 
00239        if (src==NULL) {
00240               return 0;
00241        }
00242 
00243        /* We need the orinal image with each safe neoghb. pixel */
00244        srcback = gdImageCreateTrueColor (src->sx, src->sy);
00245        if (srcback==NULL) {
00246               return 0;
00247        }
00248 
00249        gdImageSaveAlpha(srcback, 1);
00250        new_pxl = gdImageColorAllocateAlpha(srcback, 0, 0, 0, 127);
00251        gdImageFill(srcback, 0, 0, new_pxl);
00252 
00253        gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
00254 
00255        f = GET_PIXEL_FUNCTION(src);
00256 
00257        for ( y=0; y<src->sy; y++) {
00258               for(x=0; x<src->sx; x++) {
00259                      new_r = new_g = new_b = 0;
00260                      new_a = gdImageAlpha(srcback, pxl);
00261 
00262                      for (j=0; j<3; j++) {
00263                             int yv = MIN(MAX(y - 1 + j, 0), src->sy - 1);
00264                             for (i=0; i<3; i++) {
00265                                     pxl = f(srcback, MIN(MAX(x - 1 + i, 0), src->sx - 1), yv);
00266                                    new_r += (float)gdImageRed(srcback, pxl) * filter[j][i];
00267                                    new_g += (float)gdImageGreen(srcback, pxl) * filter[j][i];
00268                                    new_b += (float)gdImageBlue(srcback, pxl) * filter[j][i];
00269                             }
00270                      }
00271 
00272                      new_r = (new_r/filter_div)+offset;
00273                      new_g = (new_g/filter_div)+offset;
00274                      new_b = (new_b/filter_div)+offset;
00275 
00276                      new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
00277                      new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
00278                      new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
00279 
00280                      new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
00281                      if (new_pxl == -1) {
00282                             new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
00283                      }
00284                      gdImageSetPixel (src, x, y, new_pxl);
00285               }
00286        }
00287        gdImageDestroy(srcback);
00288        return 1;
00289 }
00290 
00291 int gdImageSelectiveBlur( gdImagePtr src)
00292 {
00293        int         x, y, i, j;
00294        float       new_r, new_g, new_b;
00295        int         new_pxl, cpxl, pxl, new_a=0;
00296        float flt_r [3][3];
00297        float flt_g [3][3];
00298        float flt_b [3][3];
00299        float flt_r_sum, flt_g_sum, flt_b_sum;
00300 
00301        gdImagePtr srcback;
00302        typedef int (*FuncPtr)(gdImagePtr, int, int);
00303        FuncPtr f;
00304 
00305        if (src==NULL) {
00306               return 0;
00307        }
00308 
00309        /* We need the orinal image with each safe neoghb. pixel */
00310        srcback = gdImageCreateTrueColor (src->sx, src->sy);
00311        if (srcback==NULL) {
00312               return 0;
00313        }
00314        gdImageCopy(srcback, src,0,0,0,0,src->sx,src->sy);
00315 
00316        f = GET_PIXEL_FUNCTION(src);
00317 
00318        for(y = 0; y<src->sy; y++) {
00319               for (x=0; x<src->sx; x++) {
00320                     flt_r_sum = flt_g_sum = flt_b_sum = 0.0;
00321                      cpxl = f(src, x, y);
00322 
00323                      for (j=0; j<3; j++) {
00324                             for (i=0; i<3; i++) {
00325                                    if ((j == 1) && (i == 1)) {
00326                                           flt_r[1][1] = flt_g[1][1] = flt_b[1][1] = 0.5;
00327                                    } else {
00328                                           pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
00329                                           new_a = gdImageAlpha(srcback, pxl);
00330 
00331                                           new_r = ((float)gdImageRed(srcback, cpxl)) - ((float)gdImageRed (srcback, pxl));
00332 
00333                                           if (new_r < 0.0f) {
00334                                                  new_r = -new_r;
00335                                           }
00336                                           if (new_r != 0) {
00337                                                  flt_r[j][i] = 1.0f/new_r;
00338                                           } else {
00339                                                  flt_r[j][i] = 1.0f;
00340                                           }
00341 
00342                                           new_g = ((float)gdImageGreen(srcback, cpxl)) - ((float)gdImageGreen(srcback, pxl));
00343 
00344                                           if (new_g < 0.0f) {
00345                                                  new_g = -new_g;
00346                                           }
00347                                           if (new_g != 0) {
00348                                                  flt_g[j][i] = 1.0f/new_g;
00349                                           } else {
00350                                                  flt_g[j][i] = 1.0f;
00351                                           }
00352 
00353                                           new_b = ((float)gdImageBlue(srcback, cpxl)) - ((float)gdImageBlue(srcback, pxl));
00354 
00355                                           if (new_b < 0.0f) {
00356                                                  new_b = -new_b;
00357                                           }
00358                                           if (new_b != 0) {
00359                                                  flt_b[j][i] = 1.0f/new_b;
00360                                           } else {
00361                                                  flt_b[j][i] = 1.0f;
00362                                           }
00363                                    }
00364 
00365                                    flt_r_sum += flt_r[j][i];
00366                                    flt_g_sum += flt_g[j][i];
00367                                    flt_b_sum += flt_b [j][i];
00368                             }
00369                      }
00370 
00371                      for (j=0; j<3; j++) {
00372                             for (i=0; i<3; i++) {
00373                                    if (flt_r_sum != 0.0) {
00374                                           flt_r[j][i] /= flt_r_sum;
00375                                    }
00376                                    if (flt_g_sum != 0.0) {
00377                                           flt_g[j][i] /= flt_g_sum;
00378                                    }
00379                                    if (flt_b_sum != 0.0) {
00380                                           flt_b [j][i] /= flt_b_sum;
00381                                    }
00382                             }
00383                      }
00384 
00385                      new_r = new_g = new_b = 0.0;
00386 
00387                      for (j=0; j<3; j++) {
00388                             for (i=0; i<3; i++) {
00389                                    pxl = f(src, x-(3>>1)+i, y-(3>>1)+j);
00390                                    new_r += (float)gdImageRed(srcback, pxl) * flt_r[j][i];
00391                                    new_g += (float)gdImageGreen(srcback, pxl) * flt_g[j][i];
00392                                    new_b += (float)gdImageBlue(srcback, pxl) * flt_b[j][i];
00393                             }
00394                      }
00395 
00396                      new_r = (new_r > 255.0f)? 255.0f : ((new_r < 0.0f)? 0.0f:new_r);
00397                      new_g = (new_g > 255.0f)? 255.0f : ((new_g < 0.0f)? 0.0f:new_g);
00398                      new_b = (new_b > 255.0f)? 255.0f : ((new_b < 0.0f)? 0.0f:new_b);
00399                      new_pxl = gdImageColorAllocateAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
00400                      if (new_pxl == -1) {
00401                             new_pxl = gdImageColorClosestAlpha(src, (int)new_r, (int)new_g, (int)new_b, new_a);
00402                      }
00403                      gdImageSetPixel (src, x, y, new_pxl);
00404               }
00405        }
00406        gdImageDestroy(srcback);
00407        return 1;
00408 }
00409 
00410 int gdImageEdgeDetectQuick(gdImagePtr src)
00411 {
00412        float filter[3][3] = {{-1.0,0.0,-1.0},
00413                             {0.0,4.0,0.0},
00414                             {-1.0,0.0,-1.0}};
00415 
00416        return gdImageConvolution(src, filter, 1, 127);
00417 }
00418 
00419 int gdImageGaussianBlur(gdImagePtr im)
00420 {
00421        float filter[3][3] = {{1.0,2.0,1.0},
00422                             {2.0,4.0,2.0},
00423                             {1.0,2.0,1.0}};
00424 
00425        return gdImageConvolution(im, filter, 16, 0);
00426 }
00427 
00428 int gdImageEmboss(gdImagePtr im)
00429 {
00430 /*
00431        float filter[3][3] = {{1.0,1.0,1.0},
00432                             {0.0,0.0,0.0},
00433                             {-1.0,-1.0,-1.0}};
00434 */
00435        float filter[3][3] = {{ 1.5, 0.0, 0.0},
00436                              { 0.0, 0.0, 0.0},
00437                              { 0.0, 0.0,-1.5}};
00438 
00439        return gdImageConvolution(im, filter, 1, 127);
00440 }
00441 
00442 int gdImageMeanRemoval(gdImagePtr im)
00443 {
00444        float filter[3][3] = {{-1.0,-1.0,-1.0},
00445                             {-1.0,9.0,-1.0},
00446                             {-1.0,-1.0,-1.0}};
00447 
00448        return gdImageConvolution(im, filter, 1, 0);
00449 }
00450 
00451 int gdImageSmooth(gdImagePtr im, float weight)
00452 {
00453        float filter[3][3] = {{1.0,1.0,1.0},
00454                             {1.0,0.0,1.0},
00455                             {1.0,1.0,1.0}};
00456 
00457        filter[1][1] = weight;
00458 
00459        return gdImageConvolution(im, filter, weight+8, 0);
00460 }
00461 /* End filters function */