diff --git a/public/png8.png b/public/png8.png new file mode 100644 index 00000000..d85fd36e Binary files /dev/null and b/public/png8.png differ diff --git a/src/Intervention/Image/Image.php b/src/Intervention/Image/Image.php index 66f1d342..d8bf2105 100644 --- a/src/Intervention/Image/Image.php +++ b/src/Intervention/Image/Image.php @@ -1162,6 +1162,41 @@ class Image return $this; } + /** + * Set a maximum number of colors for the current image + * + * @param integer $count + * @param mixed $matte + * @return Image + */ + public function limitColors($count = null, $matte = null) + { + // create empty canvas + $resource = imagecreatetruecolor($this->width, $this->height); + + // define matte + $matte = is_null($matte) ? imagecolorallocatealpha($resource, 0, 0, 0, 127) : $this->parseColor($matte); + + // fill with matte and copy original image + imagefill($resource, 0, 0, $matte); + + // set transparency + imagecolortransparent($resource, $matte); + + // copy original image + imagecopy($resource, $this->resource, 0, 0, 0, 0, $this->width, $this->height); + + if (is_numeric($count) && $count <= 256) { + // decrease colors + imagetruecolortopalette($resource, true, intval($count)); + } + + // set new resource + $this->resource = $resource; + + return $this; + } + /** * Reset to original image resource * diff --git a/tests/ImageTest.php b/tests/ImageTest.php index 28f2c261..f51bff35 100644 --- a/tests/ImageTest.php +++ b/tests/ImageTest.php @@ -1193,6 +1193,49 @@ class ImageTest extends PHPUnit_Framework_Testcase $this->assertEquals($img->height, 600); } + public function testLimitColors() + { + // reduce colors + $img = Image::make('public/test.jpg'); + $img->limitColors(10); + $this->assertEquals(imagecolorstotal($img->resource), 11); + + // reduce colors + keep transparency with matte + $img = Image::make('public/mask2.png'); + $img->limitColors(10, '#ff0000'); // red matte + $this->assertEquals(imagecolorstotal($img->resource), 11); + $color1 = $img->pickColor(0, 0); // full transparent + $color2 = $img->pickColor(9, 17); // part of matte gradient + $this->assertEquals($color1['r'], 255); + $this->assertEquals($color1['g'], 0); + $this->assertEquals($color1['b'], 0); + $this->assertEquals($color1['a'], 0); + $this->assertEquals($color2['r'], 252); + $this->assertEquals($color2['g'], 10); + $this->assertEquals($color2['b'], 11); + $this->assertEquals($color2['a'], 1); + + // increase colors + $img = Image::make('public/png8.png'); + $img->limitColors(null); // set image to true color + $this->assertEquals(imagecolorstotal($img->resource), 0); + + // increase colors + keep transparency with matte + $img = Image::make('public/png8.png'); + $img->limitColors(null); // set image to true color + $this->assertEquals(imagecolorstotal($img->resource), 0); + $color1 = $img->pickColor(0, 0); // full transparent + $color2 = $img->pickColor(10, 10); // solid color + $this->assertEquals($color1['r'], 0); + $this->assertEquals($color1['g'], 0); + $this->assertEquals($color1['b'], 0); + $this->assertEquals($color1['a'], 0); + $this->assertEquals($color2['r'], 140); + $this->assertEquals($color2['g'], 140); + $this->assertEquals($color2['b'], 140); + $this->assertEquals($color2['a'], 1); + } + public function testSaveImage() { $save_as = 'public/test2.jpg';