public function resize($blocks, $newW, $newH)
{
$images = $this->splitFrames($blocks);
// Loop on individual images and resize them using Gd
$firstFrameGd = null;
foreach ($images as $imageIndex => $image) {
$hex = $this->encode($image);
$binaryRaw = pack('H*', $hex);
// Utilize gd for resizing
$old = imagecreatefromstring($binaryRaw);
$width = imagesx($old);
$height = imagesy($old);
$new = imagecreatetruecolor($newW, $newH);
// Create a blank image
if ($firstFrameGd) {
$new = $firstFrameGd;
}
// Account for frame imageLeft and imageTop
$cX = $newW / $blocks['canvasWidth'];
// change x
$dX = $image['frames'][0]['imageLeft'];
$cY = $newH / $blocks['canvasHeight'];
$dY = $image['frames'][0]['imageTop'];
imagecopyresampled($new, $old, $dX * $cX, $dY * $cY, 0, 0, $image['frames'][0]['imageWidth'] * $cX, $image['frames'][0]['imageHeight'] * $cY, $width, $height);
ob_start();
imagegif($new);
$binaryRaw = ob_get_contents();
ob_end_clean();
if ($firstFrameGd === null) {
$firstFrameGd = $new;
}
// Hex of resized
$bytes = $this->load($binaryRaw);
$hexNew = $this->decode($bytes);
// Update original frames with hex from resized frames
$blocks['frames'][$imageIndex]['imageWidth'] = $hexNew['frames'][0]['imageWidth'];
$blocks['frames'][$imageIndex]['imageHeight'] = $hexNew['frames'][0]['imageHeight'];
$blocks['frames'][$imageIndex]['imageLeft'] = $hexNew['frames'][0]['imageLeft'];
$blocks['frames'][$imageIndex]['imageTop'] = $hexNew['frames'][0]['imageTop'];
$blocks['frames'][$imageIndex]['imageData'] = $hexNew['frames'][0]['imageData'];
// We use local color tables on each frame. This will result in faster processing since we dont have to process the global color table at the cost of a larger file size.
$blocks['frames'][$imageIndex]['localColorTableFlag'] = $hexNew['globalColorTableFlag'];
$blocks['frames'][$imageIndex]['localColorTable'] = $hexNew['globalColorTable'];
$blocks['frames'][$imageIndex]['sizeOfLocalColorTable'] = $hexNew['sizeOfGlobalColorTable'];
$blocks['frames'][$imageIndex]['transparentColorFlag'] = 0;
}
// Update dimensions or else imagecreatefromgif will choke.
$blocks['canvasWidth'] = $newW;
$blocks['canvasHeight'] = $newH;
// Disable flickering bug. Also we are using localColorTable anyways.
$blocks['globalColorTableFlag'] = 0;
$blocks['globalColorTable'] = '';
return $blocks;
}
/** * Resize helper function. * * @param Image $image * @param int $newWidth * @param int $newHeight * @param int $targetX * @param int $targetY * @param int $srcX * @param int $srcY * */ private function _resize(&$image, $newWidth, $newHeight, $targetX = 0, $targetY = 0, $srcX = 0, $srcY = 0) { // $this->_imageCheck(); if ($image->isAnimated()) { // Animated GIF $gift = new GifHelper(); $blocks = $gift->resize($image->getBlocks(), $newWidth, $newHeight); // Resize image instance $image = new Image($image->getCore(), $image->getImageFile(), $newWidth, $newHeight, $image->getType(), $blocks, true); } else { // Create blank image $newImage = Image::createBlank($newWidth, $newHeight); if (ImageType::PNG === $image->getType()) { // Preserve PNG transparency $newImage->fullAlphaMode(true); } imagecopyresampled($newImage->getCore(), $image->getCore(), $targetX, $targetY, $srcX, $srcY, $newWidth, $newHeight, $image->getWidth(), $image->getHeight()); // Free memory of old resource imagedestroy($image->getCore()); // Resize image instance $image = new Image($newImage->getCore(), $image->getImageFile(), $newWidth, $newHeight, $image->getType()); } }