Изменение размера миниатюры PHP с пропорциями - PullRequest
3 голосов
/ 04 января 2011

Вкратце, я сейчас создаю сайт типа знакомств.Пользователи могут создавать учетные записи и загружать фотографии профиля (до 8).Чтобы отобразить их в области просмотра веб-сайта, я ищу способ в PHP (со сторонним процессором / скриптами) изменить размер всех загружаемых изображений, чтобы иметь эскизы, соответствующие определенным размерам.

КакНапример, я хочу, чтобы изображения профиля (миниатюры) не превышали 120 * 150 пикселей.Сценарии должны изменять размер загруженных изображений (независимо от того, являются ли они портретными или альбомными, независимо от пропорций), чтобы соответствовать этим размерам без растяжения.

Ширина (например, 120 пикселей) всегда должна оставаться неизменной,но высота (например, 150 пикселей) может варьироваться, чтобы сохранить пропорции изображения.Если это пейзажная фотография, я предполагаю, что сценарий должен будет вырезать фрагмент из середины изображения?

Причина, по которой размер всех изображений должен быть изменен, заключается в том, что когда профили отображаются в сеткечто все миниатюры примерно одинакового размера.

Любой вклад будет принят с благодарностью.

Ответы [ 6 ]

10 голосов
/ 04 января 2011
$maxwidth = 120;
$maxheight = 150;

$img = imagecreatefromjpeg($jpgimage); 
//or imagecreatefrompng,imagecreatefromgif,etc. depending on user's uploaded file extension

$width = imagesx($img); //get width and height of original image
$height = imagesy($img);

//determine which side is the longest to use in calculating length of the shorter side, since the longest will be the max size for whichever side is longest.    
if ($height > $width) 
{   
$ratio = $maxheight / $height;  
$newheight = $maxheight;
$newwidth = $width * $ratio; 
}
else 
{
$ratio = $maxwidth / $width;   
$newwidth = $maxwidth;  
$newheight = $height * $ratio;   
}

//create new image resource to hold the resized image
$newimg = imagecreatetruecolor($newwidth,$newheight); 

$palsize = ImageColorsTotal($img);  //Get palette size for original image
for ($i = 0; $i < $palsize; $i++) //Assign color palette to new image
{ 
$colors = ImageColorsForIndex($img, $i);   
ImageColorAllocate($newimg, $colors['red'], $colors['green'], $colors['blue']);
} 

//copy original image into new image at new size.
imagecopyresized($newimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

imagejpeg($newimg,$outputfile); //$output file is the path/filename where you wish to save the file.  
//Have to figure that one out yourself using whatever rules you want.  Can use imagegif() or imagepng() or whatever.

Это позволит уменьшить любые изображения пропорционально в зависимости от того, какая сторона длиннее (ширина или высота), до максимального размера.Это также взорвет любые изображения, меньшие, чем максимум, что вы можете остановить с небольшой проверкой того, меньше ли их ширина и высота, чем их максимум.Таким образом, изображение 200x300 будет сокращено до 100x150, а изображение 300x200 будет уменьшено до 120x80.

Хм, вы хотите, чтобы ширина всегда была 120, поэтому она немного изменится, и да, это будетприходится вырезать что-то в случае с изображением, например, 200x300, потому что оно будет уменьшено до 120x180 без каких-либо искажений, или потребуется уменьшить его еще больше и пометить его почтовыми ящиками, но это поможет вам начать хорошо.

Создание почтовых ящиков в этом примере просто потребует выяснения, какими будут правильные x и y для начала рисования нового изображения в функции imagecopyresized ().В случае чего-то вроде 100x150, X будет 10, я думаю, так что с каждой стороны будет 10px пустого пространства для 120x150 в конце.Размер почтового ящика 120x80 X будет 0, но Y будет 35, поэтому для 120x150 будет 35 пикселей пустого пространства выше и ниже.

Вы также хотели бы сделать $ newimg с $ maxwidth, $ maxheight, а не $newwidth, $ newheight, но imagecopyresized () по-прежнему будет использовать оба значения $ new.

Так как мне скучно и больше ничего не нужно делать, эти изменения сделают это:

if ($height > $width) 
{   
$ratio = $maxheight / $height;  
$newheight = $maxheight;
$newwidth = $width * $ratio; 
$writex = round(($maxwidth - $newwidth) / 2);
$writey = 0;
{
else 
{
$ratio = $maxwidth / $width;   
$newwidth = $maxwidth;  
$newheight = $height * $ratio;   
$writex = 0;
$writey = round(($maxheight - $newheight) / 2);
}

$newimg = imagecreatetruecolor($maxwidth,$maxheight);

//Since you probably will want to set a color for the letter box do this
//Assign a color for the letterbox to the new image, 
//since this is the first call, for imagecolorallocate, it will set the background color
//in this case, black rgb(0,0,0)
imagecolorallocate($newimg,0,0,0);

//Loop Palette assignment stuff here

imagecopyresized($newimg, $img, $writex, $writey, 0, 0, $newwidth, $newheight, $width, $height);

Это должно сработать, еще не пробовал.

2 голосов
/ 04 января 2011

GD или функции Imagick - это то, что вам нужно в зависимости от конфигурации PHP.
Извините, я новичок. Я не могу опубликовать обе ссылки в одном сообщении :(

1 голос
/ 07 февраля 2013

Мне недавно понадобилось решение для изменения размера php (миниатюры), и я нашел Zebra_Image library , которая представляет собой облегченную библиотеку для работы с изображениями, написанную на PHP. Код действительно чистый и простой в использовании. Я настоятельно рекомендую использовать эту библиотеку. Пример кода достаточно, чтобы вы начали.

Убедитесь, что в файле php.ini установлено достаточное количество памяти для работы с изображениями с относительно большим разрешением (например, 2560x1600). У меня была ошибка с большими изображениями, и не было ошибок для печати. Я отладил проблему до imagecreatefrom{gif,jpeg,png} вызовов в function _create_from_source в строках 1262 , 1279 и 1288 . Звонки были прерваны с помощью @, поэтому я не смог изменить ошибку. Я удалил @ lines и увидел ошибку PHP, что предел памяти превышен. Исходный предел памяти был установлен на 32 МБ, и я увеличил его до 64 МБ. Теперь я могу манипулировать 2560x1600, и я отказываюсь манипулировать изображениями большего размера.

Ниже приведен пример кода для управления разрешением изображения.

    $image_properties = getimagesize($UPLOADED_FILE_PATH);                   
    $file_width = $image_properties[0];                                
    $file_height = $image_properties[1];                               

    if ($file_width > 2560 || $file_height > 1600) {    
        // handle your error whichever you like, I simply 'die' just to show               
        die('Cannot manipulate image bigger than 2560x1600');                                                                                                                                              
    }       

(Примечание: я использую Zebra Image версии 2.2.2)

0 голосов
/ 09 марта 2019

Некоторые говорят, что быстрее, я использую следующий

    
    function resizeImageProportional($imagePath, $destinationPath, $width = false, $height = false, $filterType = \Imagick::FILTER_POINT, $blur = 1, $bestFit = false, $cropZoom = false)
    {
        if (!$width && !$height) {
            trigger_error("WTF_IMAGE_RESIZE");
            return false;
        }
        //The blur factor where > 1 is blurry, < 1 is sharp.
        $imagick = new \Imagick(realpath($imagePath));</p>

    if (!$width || !$height) {
        $orig_width = $imagick->getImageWidth();
        $orig_height = $imagick->getImageHeight();
        $proportion = $orig_height/$orig_width;
        if (!$width) {
            $width = $height*$proportion;
        } elseif (!$height) {
            $height = $width*$proportion;
        }
    }

    if ($bestFit) {
        $imagick->resizeImage($width, $height, $filterType, $blur, $bestFit);
    } else {
        $imagick->resizeImage($width, $height, $filterType, $blur);
    }

    if ($cropZoom) {
        $cropWidth = $imagick->getImageWidth();
        $cropHeight = $imagick->getImageHeight();

        $newWidth = $cropWidth / 2;
        $newHeight = $cropHeight / 2;

        $imagick->cropimage(
            $newWidth,
            $newHeight,
            ($cropWidth - $newWidth) / 2,
            ($cropHeight - $newHeight) / 2
        );

        $imagick->scaleimage(
            $imagick->getImageWidth() * 4,
            $imagick->getImageHeight() * 4
        );
    }
0 голосов
/ 04 января 2011

вам не нужно воображение.Вот ссылка, которая приведет вас к функции, которая изменит размер любого изображения с помощью PHP GD до любого произвольного размера.функция имеет опции для использования почтовых ящиков или методов кадрирования, чтобы изменить размер к новому соотношению сторон.функция также подробно объясняется.проверьте это.

http://www.spotlesswebdesign.com/blog.php?id=1

, если это то, что вы ищете, установите флажок рядом с этим ответом.спасибо!

0 голосов
/ 04 января 2011

Вы можете сделать это с помощью ImageMagick :

convert susan.jpg -resize x200 susan_thumb.jpg

Это выполняется с помощью команды оболочки, поэтому в PHP вы используете shell_exec() для запуска вышеуказанной команды.Я не думаю, что вам нужны какие-либо расширения PHP.

В документации ImageMagick можно найти несколько флагов для управления операцией изменения размера.Если я правильно помню, x200 перед числом означает «масштаб с таким же соотношением сторон до 200px».

Я написал руководство по установке для ImageMagick (и ghostscript): Как установить, протестироватьПреобразуйте, изменяйте размер PDF, используя ImageMagick, Ghostscript, Windows Vista / 7 x64 , основываясь на моей неуклюжести, возможно, это может вам помочь.

Другой вариант - библиотека GD (подробности в ответе dqhendricks)Это быстрее и, очевидно, лучше документировано, используется для основных операций.

...