Last active
November 5, 2019 20:05
-
-
Save jarodium/407b70ac41d7fd4c6837565e46474e90 to your computer and use it in GitHub Desktop.
Predominant color with VIPS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require '../vendor/autoload.php'; | |
use Jcupitt\Vips; | |
Vips\Config::concurrencySet(2); | |
Vips\Config::CacheSetMax(0); | |
//header("Content-type: text/plain"); | |
//var_dump($_REQUEST); | |
$mime = "jpeg"; | |
$ext = ".jpg"; | |
$desired_width = 800; | |
$f = filter_var($_REQUEST["uri"],FILTER_SANITIZE_STRING); | |
header("Content-type: image/".$mime); | |
//open our huge image and thumbnail it to a buffer | |
//$image = Vips\Image::newFromFile("produtos/capricorn-4315367.jpg"); | |
$image = Vips\Image::thumbnail("produtos/capricorn-4315367.jpg", 100); | |
//calculate aspect ratio for guessing the height of final image | |
$aspectRatio = $image->height / $image->width; | |
/* Keep the width fix at $desired_width, but change the height according to the aspect ratio */ | |
$desired_height = (int)($aspectRatio * $desired_width); | |
//quality 1 will pixelate as intended | |
$buffer = $image->writeToBuffer($ext,["Q" => 1]); //Karen Stadfelt reference here, Code Geass fans xD | |
//load image from buffer | |
$image2 = Vips\Image::newFromBuffer($buffer, '', ['sequential' => true]); | |
//i could get the average, but I want the dominant color | |
//https://stackoverflow.com/questions/3468500/detect-overall-average-color-of-the-picture | |
$block_size = 20; | |
$colors = []; | |
for($x=0; $x<$image2->width; $x += $block_size) { | |
for($y=0; $y<$image2->height; $y += $block_size) { | |
$rgb = $image2->getpoint($x, $y); | |
$red = round(round(($rgb[0] / 0x33)) * 0x33); | |
$green = round(round(($rgb[1] / 0x33)) * 0x33); | |
$blue = round(round(($rgb[2] / 0x33)) * 0x33); | |
$hexRGB = sprintf('%02X%02X%02X', $red, $green, $blue); //line is only usefull when dumping for HTML | |
$strRGB = $rgb[0].",".$rgb[1].",".$rgb[2]; | |
if(array_key_exists($strRGB, $colors)) { | |
$colors[$strRGB]++; | |
} | |
else { | |
$colors[$strRGB] = 1; | |
} | |
} | |
} | |
arsort($colors); | |
//var_dump($colors); | |
$rgb = array_key_first($colors); | |
$rgb = explode(",",$rgb); | |
$colors = []; //free mem space? | |
//create a new image and then fill it with $rgb | |
//I find my lack of VIPS knowledge, disturbing | |
//var_dump($rgb); | |
$im = @imagecreatetruecolor($desired_width, $desired_height) or die("Cannot Initialize new GD image stream"); | |
$bg = imagecolorallocate($im, (int)$rgb[0] , (int)$rgb[1], (int)$rgb[2]); | |
imagefill($im, 0, 0, $bg); | |
imagejpeg($im); | |
imagedestroy($im); | |
//echo $buffer; | |
exit; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$block_size = 25; | |
$colors = []; | |
/* | |
As instructed in https://github.com/libvips/php-vips/issues/92#issuecomment-549765148, | |
we make a fast thumbnail to 16 and then pixelate with resize | |
*/ | |
$thumb = Vips\Image::thumbnail($f, 16); | |
$placeholder = $thumb->resize($desired_width / $thumb->width, [ | |
'scale' => $desired_height / $thumb->height, | |
'kernel' => 'nearest' | |
]); | |
/* then we create an image from a buffer with sequential access to get pixel information with a block_size, | |
previously measured in Shop or Gimp | |
*/ | |
$placeholder = Vips\Image::newFromBuffer($placeholder->writeToBuffer($ext), '', ['sequential' => true]); | |
for($x=0; $x<$placeholder->width; $x += $block_size) { | |
for($y=0; $y<$placeholder->height; $y += $block_size) { | |
$rgb = $placeholder->getpoint($x, $y); | |
$red = round(round(($rgb[0] / 0x33)) * 0x33); | |
$green = round(round(($rgb[1] / 0x33)) * 0x33); | |
$blue = round(round(($rgb[2] / 0x33)) * 0x33); | |
$hexRGB = "#".sprintf('%02X%02X%02X', $red, $green, $blue); //line is only usefull when dumping for HTML | |
//$strRGB = $rgb[0].",".$rgb[1].",".$rgb[2]; | |
if(array_key_exists($hexRGB, $colors)) { | |
$colors[$hexRGB]++; | |
} | |
else { | |
$colors[$hexRGB] = 1; | |
} | |
} | |
} | |
arsort($colors); | |
$rgb = array_key_first($colors); | |
list($alpha, $red, $green, $blue) = parse($rgb); //parse function in https://gist.github.com/kleisauke/a8cdd74c63738eb3add7d9422458aed8 | |
$thumb = null; | |
$placeholder = null; | |
$colors = []; | |
//this part is in https://gist.github.com/kleisauke/a8cdd74c63738eb3add7d9422458aed8 | |
// Make a 1x1 pixel with the red channel and cast it to provided format. | |
$pixel = Vips\Image::black(1, 1)->add($red)->cast(Vips\BandFormat::UCHAR); | |
// Extend this 1x1 pixel to match the origin image dimensions. | |
$image = $pixel->embed(0, 0, $desired_width, $desired_height, ['extend' => Vips\Extend::COPY]); | |
// Ensure that the interpretation of the image is set. | |
$image = $image->copy(['interpretation' => Vips\Interpretation::SRGB]); | |
// Bandwise join the rest of the channels including the alpha channel. | |
$image = $image->bandjoin([ | |
$green, | |
$blue, | |
$alpha | |
]); | |
$buffer = $image->writeToBuffer($ext); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment