]> granicus.if.org Git - php/commitdiff
MFH: added pixelate filter.
authorTakeshi Abe <tabe@php.net>
Wed, 14 Jan 2009 19:06:12 +0000 (19:06 +0000)
committerTakeshi Abe <tabe@php.net>
Wed, 14 Jan 2009 19:06:12 +0000 (19:06 +0000)
ext/gd/config.m4
ext/gd/config.w32
ext/gd/gd.c
ext/gd/libgd/gd.h
ext/gd/libgd/gd_pixelate.c [new file with mode: 0644]
ext/gd/tests/imagefilter.phpt

index 7226deb52540b6bb40df70213ce665ec03ab9a8c..aa4371d191c158a0f1ddf5a1524e25d0bbfe1a5a 100644 (file)
@@ -268,7 +268,7 @@ if test "$PHP_GD" = "yes"; then
                  libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c libgd/gdfontmb.c libgd/gdfontl.c \
                  libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c libgd/gdcache.c libgd/gdkanji.c \
                  libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c libgd/gd_topal.c libgd/gd_gif_in.c \
-                 libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c"
+                 libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c libgd/gd_pixelate.c"
 
 dnl check for fabsf and floorf which are available since C99
   AC_CHECK_FUNCS(fabsf floorf)
index ff4506a1b1cd6eec2231fe73053548594d772b6c..7a741f3bc2484097292fe52a3bff3fb956a5a6ac 100644 (file)
@@ -33,7 +33,7 @@ if (PHP_GD != "no") {
                        gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \
                        gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \
                        gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \
-                       gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c gd_security.c", "gd");
+                       gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c gd_security.c gd_pixelate.c", "gd");
                AC_DEFINE('HAVE_LIBGD', 1, 'GD support');
                ADD_FLAG("CFLAGS_GD", " \
 /D HAVE_GD_DYNAMIC_CTX_EX=1 \
index 63a9aa80589265a6fdb6598c9633799be4c86863..f012d9a5e5d63e1b60d4f9642f61d35ef13a42b8 100644 (file)
@@ -141,7 +141,8 @@ int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b);
 #define IMAGE_FILTER_SELECTIVE_BLUR 8
 #define IMAGE_FILTER_MEAN_REMOVAL   9
 #define IMAGE_FILTER_SMOOTH         10
-#define IMAGE_FILTER_MAX            10
+#define IMAGE_FILTER_PIXELATE       11
+#define IMAGE_FILTER_MAX            11
 #define IMAGE_FILTER_MAX_ARGS       5
 static void php_image_filter_negate(INTERNAL_FUNCTION_PARAMETERS);
 static void php_image_filter_grayscale(INTERNAL_FUNCTION_PARAMETERS);
@@ -154,6 +155,7 @@ static void php_image_filter_gaussian_blur(INTERNAL_FUNCTION_PARAMETERS);
 static void php_image_filter_selective_blur(INTERNAL_FUNCTION_PARAMETERS);
 static void php_image_filter_mean_removal(INTERNAL_FUNCTION_PARAMETERS);
 static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS);
+static void php_image_filter_pixelate(INTERNAL_FUNCTION_PARAMETERS);
 #endif
 /* End Section filters declarations */
 static gdImagePtr _php_image_create_from_string (zval **Data, char *tn, gdImagePtr (*ioctx_func_p)() TSRMLS_DC);
@@ -1187,6 +1189,7 @@ PHP_MINIT_FUNCTION(gd)
        REGISTER_LONG_CONSTANT("IMG_FILTER_EMBOSS", IMAGE_FILTER_EMBOSS, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("IMG_FILTER_MEAN_REMOVAL", IMAGE_FILTER_MEAN_REMOVAL, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("IMG_FILTER_PIXELATE", IMAGE_FILTER_PIXELATE, CONST_CS | CONST_PERSISTENT);
        /* End Section Filters */
 #else
        REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT);
@@ -4915,6 +4918,29 @@ static void php_image_filter_smooth(INTERNAL_FUNCTION_PARAMETERS)
        RETURN_FALSE;
 }
 
+static void php_image_filter_pixelate(INTERNAL_FUNCTION_PARAMETERS)
+{
+       zval *IM;
+       gdImagePtr im;
+       long tmp, blocksize, mode = 0;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll|l", &IM, &tmp, &blocksize, &mode) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+
+       if (im == NULL) {
+               RETURN_FALSE;
+       }
+
+       if (gdImagePixelate(im, (int) blocksize, (const unsigned int) mode)) {
+               RETURN_TRUE;
+       }
+
+       RETURN_FALSE;
+}
+
 /* {{{ proto bool imagefilter(resource src_im, int filtertype, [args] )
    Applies Filter an image using a custom angle */
 PHP_FUNCTION(imagefilter)
@@ -4935,7 +4961,8 @@ PHP_FUNCTION(imagefilter)
                php_image_filter_gaussian_blur,
                php_image_filter_selective_blur,
                php_image_filter_mean_removal,
-               php_image_filter_smooth
+               php_image_filter_smooth,
+               php_image_filter_pixelate
        };
 
        if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 6) {
index 5df48271c12c0f6dc6341bca7d6edf4bcfeac99c..77c98903ad62454f4c18c542558e37e2e1310ebb 100644 (file)
@@ -580,6 +580,13 @@ void gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg);
 void gdImageAntialias(gdImagePtr im, int antialias);
 void gdImageSaveAlpha(gdImagePtr im, int saveAlphaArg);
 
+enum gdPixelateMode {
+       GD_PIXELATE_UPPERLEFT,
+       GD_PIXELATE_AVERAGE
+};
+
+int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode);
+
 /* Macros to access information about images. */
 
 /* Returns nonzero if the image is a truecolor image,
diff --git a/ext/gd/libgd/gd_pixelate.c b/ext/gd/libgd/gd_pixelate.c
new file mode 100644 (file)
index 0000000..3808a6e
--- /dev/null
@@ -0,0 +1,57 @@
+#include "gd.h"
+
+int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode)
+{
+       int x, y;
+
+       if (block_size <= 0) {
+               return 0;
+       } else if (block_size == 1) {
+               return 1;
+       }
+       switch (mode) {
+       case GD_PIXELATE_UPPERLEFT:
+               for (y = 0; y < im->sy; y += block_size) {
+                       for (x = 0; x < im->sx; x += block_size) {
+                               if (gdImageBoundsSafe(im, x, y)) {
+                                       int c = gdImageGetPixel(im, x, y);
+                                       gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c);
+                               }
+                       }
+               }
+               break;
+       case GD_PIXELATE_AVERAGE:
+               for (y = 0; y < im->sy; y += block_size) {
+                       for (x = 0; x < im->sx; x += block_size) {
+                               int a, r, g, b, c;
+                               int total;
+                               int cx, cy;
+
+                               a = r = g = b = c = total = 0;
+                               /* sampling */
+                               for (cy = 0; cy < block_size; cy++) {
+                                       for (cx = 0; cx < block_size; cx++) {
+                                               if (!gdImageBoundsSafe(im, x + cx, y + cy)) {
+                                                       continue;
+                                               }
+                                               c = gdImageGetPixel(im, x + cx, y + cy);
+                                               a += gdImageAlpha(im, c);
+                                               r += gdImageRed(im, c);
+                                               g += gdImageGreen(im, c);
+                                               b += gdImageBlue(im, c);
+                                               total++;
+                                       }
+                               }
+                               /* drawing */
+                               if (total > 0) {
+                                       c = gdImageColorResolveAlpha(im, r / total, g / total, b / total, a / total);
+                                       gdImageFilledRectangle(im, x, y, x + block_size - 1, y + block_size - 1, c);
+                               }
+                       }
+               }
+               break;
+       default:
+               return 0;
+       }
+       return 1;
+}
index b3855d66f26cc8a87e89643681046681fc08e7e1..b62b5facfd57c88e63142465e95ed7b5e2857a14 100644 (file)
@@ -21,7 +21,7 @@ $no_arg_filters = array(
 
 $SAVE_DIR = dirname(__FILE__);
 $SOURCE_IMG = $SAVE_DIR . "/test.png";
-
+       
        foreach ($no_arg_filters as $filt) {
                $im = imagecreatefrompng($SOURCE_IMG);
                if (imagefilter($im, constant($filt))) {
@@ -34,7 +34,7 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png";
        }
 
        $im = imagecreatefrompng($SOURCE_IMG);
-
+       
        if (imagefilter($im, IMG_FILTER_SMOOTH, -1924.124)) {
                imagepng($im, $SAVE_DIR . "/IMG_FILTER_SMOOTH.png");
                echo "IMG_FILTER_SMOOTH success\n";
@@ -42,9 +42,9 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png";
        } else {
                echo "IMG_FILTER_SMOOTH failed\n";
        }
-
+       
        $im = imagecreatefrompng($SOURCE_IMG);
-
+       
        if (imagefilter($im, IMG_FILTER_COLORIZE, -127.12, -127.98, 127)) {
                imagepng($im, $SAVE_DIR . "/IMG_FILTER_COLORIZE.png");
                echo "IMG_FILTER_COLORIZE success\n";
@@ -52,9 +52,9 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png";
        } else {
                echo "IMG_FILTER_COLORIZE failed\n";
        }
-
+       
        $im = imagecreatefrompng($SOURCE_IMG);
-
+       
        if (imagefilter($im, IMG_FILTER_CONTRAST, -90)) {
                imagepng($im, $SAVE_DIR . "/IMG_FILTER_CONTRAST.png");
                echo "IMG_FILTER_CONTRAST success\n";
@@ -64,7 +64,7 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png";
        }
 
        $im = imagecreatefrompng($SOURCE_IMG);
-
+       
        if (imagefilter($im, IMG_FILTER_BRIGHTNESS, 98)) {
                imagepng($im, $SAVE_DIR . "/IMG_FILTER_BRIGHTNESS.png");
                echo "IMG_FILTER_BRIGHTNESS success\n";
@@ -72,6 +72,16 @@ $SOURCE_IMG = $SAVE_DIR . "/test.png";
        } else {
                echo "IMG_FILTER_BRIGHTNESS failed\n";
        }
+
+       $im = imagecreatefrompng($SOURCE_IMG);
+       
+       if (imagefilter($im, IMG_FILTER_PIXELATE, 5, 1)) {
+               imagepng($im, $SAVE_DIR . "/IMG_FILTER_PIXELATE.png");
+               echo "IMG_FILTER_PIXELATE success\n";
+               unlink($SAVE_DIR . "/IMG_FILTER_PIXELATE.png");
+       } else {
+               echo "IMG_FILTER_PIXELATE failed\n";
+       }
 ?>
 --EXPECT--
 IMG_FILTER_NEGATE success
@@ -85,3 +95,4 @@ IMG_FILTER_SMOOTH success
 IMG_FILTER_COLORIZE success
 IMG_FILTER_CONTRAST success
 IMG_FILTER_BRIGHTNESS success
+IMG_FILTER_PIXELATE success