Instantly share code, notes, and snippets.

Embed
What would you like to do?
Circular avatar optimiser: blacks out 16×16 blocks outside the circle (see: https://hikari.noyu.me/blog/2017-07-30-optimising-circular-avatars.html)
<?php declare(strict_types=1);
if ($argc !== 3) {
die("Usage: php optimise.php input.jpeg output.jpeg" . PHP_EOL);
}
$infile = $argv[1];
$outfile = $argv[2];
$img = imageCreateFromJPEG($infile);
$black = imageColorAllocate($img, 0, 0, 0);
list($width, $height) = [imageSX($img), imageSY($img)];
list($centreX, $centreY) = [$width / 2, $height / 2];
// No need to do sqrt() in distance calculations if we square the radius!
$radius = ($width / 2) ** 2;
for ($x = 0; $x < 16 * ceil($width / 16); $x += 16) {
for ($y = 0; $y < 16 * ceil($height / 16); $y += 16) {
$distTopLeft = (($centreX - $x) ** 2 + ($centreY - $y) ** 2);
$distTopRight = (($centreX - ($x + 16)) ** 2 + ($centreY - $y) ** 2);
$distBottomLeft = (($centreX - $x) ** 2 + ($centreY - ($y + 16)) ** 2);
$distBottomRight = (($centreX - ($x + 16)) ** 2 + ($centreY - ($y + 16)) ** 2);
if ($distTopLeft > $radius && $distTopRight > $radius
&& $distBottomLeft > $radius && $distBottomRight > $radius) {
imageFilledRectangle($img, $x, $y, $x + 15, $y + 15, $black);
}
}
}
imageJPEG($img, $outfile, 85);
// Run ImageMagick to remove fluff and interlace
system("magick " . escapeshellarg($outfile) . " -strip -interlace JPEG -quality 85 " . escapeshellarg($outfile));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment