Skip to content

Instantly share code, notes, and snippets.

@makoni
Created July 13, 2011 18:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save makoni/1080919 to your computer and use it in GitHub Desktop.
Save makoni/1080919 to your computer and use it in GitHub Desktop.
PHP function for resizing animated GIF with Imagick
<?php
/**
* Функция для дебага в браузере
* @param $smth - что выводить
* @param boolean $stop - остановить скрипт после вывода
*/
function dbg( $smth, $stop = false ) {
echo "<xmp>";
print_r( $smth );
echo "</xmp>";
if ( false !== $stop ) {
exit;
}
}
/**
* Функция создания квадратного изображения с кадрированием.
* @param string $sourceFile - путь до исходного файла
* @param string $destinationFile - путь файла, в который сохраняется результат
* @param integer $biggestSideSize - размер стороны квадратного изображения
* @param boolean $makeSquare - пока бесполезно, скорее задел на будущее, чтобы 1 функцией работать с Imagick
* @return
*/
function resizeImagick( $sourceFile, $destinationFile, $biggestSideSize, $makeSquare = false ){
$info = getimagesize( $sourceFile );
$destinationFile = $destinationFile . image_type_to_extension( $info[2] );
# проверяем на формат входного файла
if ( false === in_array( $info[2], array( IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG ) ) )
return false;
$originalWidth = $info[0];
$originalHeight = $info[1];
# создаём новый пустой объект
$newFileObj = new \Imagick();
# оригинальное изображение
$im = new \Imagick( $sourceFile );
if ( true === $makeSquare ){
if ( $originalWidth < $originalHeight ) {
$newWidth = $biggestSideSize;
$newHeight = 0;
} else {
$newWidth = 0;
$newHeight = $biggestSideSize;
}
$original_ratio = $originalWidth / $originalHeight;
if ($original_ratio >= 1) {
# ширина уменьшенной картинки (высота равна $biggestSideSize )
$src_w = ( $originalWidth * $biggestSideSize ) / $originalHeight;
$src_x = ( $src_w - $biggestSideSize) / 2;
$src_y = 0;
}
else {
$src_h = ( $originalHeight * $biggestSideSize) / $originalWidth;
$src_x = 0;
$src_y = ( $src_h - $biggestSideSize) / 2;
}
switch ( $info[2] ){
case IMAGETYPE_GIF:
$im = $im->coalesceImages();
foreach ( $im as $newFileObj ) {
$newFileObj->setFormat("gif");
$new_x = 0;
$new_y = 0;
$tmp_new_width = $newWidth;
$tmp_new_height = $newHeight;
$imagePage = $newFileObj->getImagePage();
# ширина и высота обрезаемой области
# вертикальная картинка
if ( $originalWidth < $originalHeight ) {
$cutedWidth = $originalWidth;
$cutedHeight = $originalWidth;
} else {
#горизонтальная картинка
$cutedWidth = $originalHeight;
$cutedHeight = $originalHeight;
}
$resize_ratio = $cutedHeight / $biggestSideSize ;
$offset_y = $imagePage['y'];
# если размер кадра не совпадает с размером самой картинки
if ( $newFileObj->getImageWidth() < $newWidth ) {
$tmp_new_width = round( $newFileObj->getImageWidth() / $resize_ratio );
$tmp_new_height = round( $newFileObj->getImageHeight() / $resize_ratio );
$offset_x = $imagePage['x'];
$new_x = round( $offset_x / $resize_ratio );
$new_y = round( $offset_y / $resize_ratio );
} else if ( $newFileObj->getImageHeight() < $newHeight ) {
$tmp_new_width = round( $newFileObj->getImageWidth() / $resize_ratio );
$tmp_new_height = round( $newFileObj->getImageHeight() / $resize_ratio );
$offset_x = $imagePage['x'] - ( $originalWidth - $cutedWidth )/2;
$new_x = round( $offset_x / $resize_ratio );
$new_y = round( $offset_y / $resize_ratio );
#dbg( 'Кадр:' . $newFileObj->getImageWidth() . 'x' . $newFileObj->getImageHeight() );
#dbg( 'Уменьшен до:' . $tmp_new_width . 'x' . $tmp_new_height );
#dbg( 'Будет размещен: ' . $new_x . ',' . $new_y . ' в поле ' . $biggestSideSize . 'x' . $biggestSideSize );
}
//Выполняется resize до 200 пикселей поширине и сколько получится по высоте (с соблюдением пропорций конечно)
$newFileObj->thumbnailImage( $tmp_new_width, $tmp_new_height );
#dbg('Кропнуть: ' . $biggestSideSize . 'x' . $biggestSideSize . ' коорд. ' . $src_x . ',' . $src_y );
#dbg( 'Кадр до кропа:' . $newFileObj->getImageWidth() . 'x' . $newFileObj->getImageHeight() );
if ( $newFileObj->getImageHeight() >= $biggestSideSize || $newFileObj->getImageWidth() >= $biggestSideSize ) {
$newFileObj->cropImage( $biggestSideSize, $biggestSideSize, $src_x, $src_y );
}
else {
$newFileObj->cropImage( $biggestSideSize, $biggestSideSize, 0, $src_y );
}
$newFileObj->setImagePage( $newFileObj->getImageWidth(), $newFileObj->getImageHeight(), $new_x, $new_y );
#dbg( 'Кадр после кропа:' . $newFileObj->getImageWidth() . 'x' . $newFileObj->getImageHeight() );
#dbg('........................');
}
$newFileObj->writeImages( $destinationFile, true);
return image_type_to_extension( $info[2], false );
break;
case IMAGETYPE_PNG:
$im->thumbnailImage( $newWidth, $newHeight );
$im->cropImage( $biggestSideSize, $biggestSideSize, $src_x, $src_y );
#$im->setImageCompressionQuality(90);
$im->writeImages( $destinationFile, true);
return image_type_to_extension( $info[2], false );
break;
case IMAGETYPE_JPEG:
$im->thumbnailImage( $newWidth, $newHeight );
$im->cropImage( $biggestSideSize, $biggestSideSize, $src_x, $src_y );
$im->setImageCompressionQuality(95);
$im->writeImages( $destinationFile, true);
return image_type_to_extension( $info[2], false );
break;
}
}
switch ( $info[2] ){
case IMAGETYPE_PNG:
$newFileObj->setFormat("png");
$im->thumbnailImage( $newWidth, $newHeight );
return $im->writeImages( $destinationFile, true);
break;
case IMAGETYPE_JPEG:
$newFileObj->setFormat("jpeg");
$im->thumbnailImage( $newWidth, $newHeight );
return $im->writeImages( $destinationFile, true);
break;
case IMAGETYPE_GIF:
$newFileObj->setFormat("gif");
foreach ( $im as $newFileObj ) {
//Выполняется resize до 200 пикселей поширине и сколько получится по высоте (с соблюдением пропорций конечно)
$newFileObj->thumbnailImage( $newWidth, $newHeight );
$newFileObj->setImagePage( $newFileObj->getImageWidth(), $newFileObj->getImageHeight(), 0, 0 );
}
return $newFileObj->writeImages( $destinationFile, true);
break;
default:
return false;
}
}
@Bort222
Copy link

Bort222 commented Sep 9, 2013

А можно как то оптимизировать полученный GIF ? Ато сейчас на выходе он весит больше чем на входе :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment