diff options
author | Takeshi Abe <tabe@php.net> | 2009-01-14 19:06:12 +0000 |
---|---|---|
committer | Takeshi Abe <tabe@php.net> | 2009-01-14 19:06:12 +0000 |
commit | 40d3b2f7f30ecc7261b48aa6d67abd635210a4cc (patch) | |
tree | a41447ba81a60a5b04e7f9391613d0d049f5aeee | |
parent | ad0935cd47a88661825d611b59576bf3e0e73fa7 (diff) | |
download | php-git-40d3b2f7f30ecc7261b48aa6d67abd635210a4cc.tar.gz |
MFH: added pixelate filter.
-rw-r--r-- | ext/gd/config.m4 | 2 | ||||
-rw-r--r-- | ext/gd/config.w32 | 2 | ||||
-rw-r--r-- | ext/gd/gd.c | 31 | ||||
-rw-r--r-- | ext/gd/libgd/gd.h | 7 | ||||
-rw-r--r-- | ext/gd/libgd/gd_pixelate.c | 57 | ||||
-rw-r--r-- | ext/gd/tests/imagefilter.phpt | 25 |
6 files changed, 113 insertions, 11 deletions
diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index 7226deb525..aa4371d191 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -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) diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index ff4506a1b1..7a741f3bc2 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -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 \ diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 63a9aa8058..f012d9a5e5 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -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) { diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h index 5df48271c1..77c98903ad 100644 --- a/ext/gd/libgd/gd.h +++ b/ext/gd/libgd/gd.h @@ -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 index 0000000000..3808a6e55d --- /dev/null +++ b/ext/gd/libgd/gd_pixelate.c @@ -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; +} diff --git a/ext/gd/tests/imagefilter.phpt b/ext/gd/tests/imagefilter.phpt index b3855d66f2..b62b5facfd 100644 --- a/ext/gd/tests/imagefilter.phpt +++ b/ext/gd/tests/imagefilter.phpt @@ -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 |