Square product thumbnails take three steps: crop the largest centered square with imagecrop(), scale it with imagescale() (bicubic is sharper than the bilinear default), and draw a watermark with imagettftext(), measured first by imagettfbbox() and made translucent by an alpha color (0 opaque, 127 clear). For a logo, use imagecopy() or imagecopymerge().
<?php
declare(strict_types=1);
function thumbnail(GdImage $src, int $size, string $mark): GdImage
{
$font = '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf';
$side = min($w = imagesx($src), $h = imagesy($src));
$thumb = imagescale(imagecrop($src, ['x' => intdiv($w - $side, 2),
'y' => intdiv($h - $side, 2), 'width' => $side, 'height' => $side]),
$size, $size, IMG_BICUBIC);
$box = imagettfbbox($pt = $size / 16, 0, $font, $mark); // 8 ints: the text's corners
imagettftext($thumb, $pt, 0, $size - ($box[2] - $box[0]) - (int) $pt, $size - (int) $pt,
imagecolorallocatealpha($thumb, 255, 255, 255, 50), $font, $mark);
return $thumb;
}
$src = imagecreatefromjpeg('books.jpg');
imagewebp(thumbnail($src, 300, '© Bookshop'), 't300.webp'); // 11,620 bytes
imagewebp(thumbnail($src, 120, '© Bookshop'), 't120.webp');
Always scale from the original. Imagick 623 crops and resizes in one call, $im->cropThumbnailImage(300, 300), and Intervention Image 14,373 (github.com/Intervention/image (https://github.com/Intervention/image 14,373 ), Comparison and Logic) puts GD and Imagick behind one fluent API.