Как изменить размер и преобразовать загруженное изображение в PNG с помощью GD? - PullRequest
9 голосов
/ 22 августа 2008

Я хочу разрешить пользователям загружать изображения аватарного типа в различных форматах ( GIF, JPEG и PNG не менее ), но сохранять их все как BLG базы данных PNG . Если изображения увеличены по пикселям, я хочу изменить их размер перед вставкой в ​​БД.

Как лучше всего использовать GD для изменения размера и преобразования PNG?

Редактировать: К сожалению, только GD доступен на сервере, который мне нужно использовать, нет ImageMagick .

Ответы [ 9 ]

24 голосов
/ 22 августа 2008
<?php                                              
/*
Resizes an image and converts it to PNG returning the PNG data as a string
*/
function imageToPng($srcFile, $maxSize = 100) {  
    list($width_orig, $height_orig, $type) = getimagesize($srcFile);        

    // Get the aspect ratio
    $ratio_orig = $width_orig / $height_orig;

    $width  = $maxSize; 
    $height = $maxSize;

    // resize to height (orig is portrait) 
    if ($ratio_orig < 1) {
        $width = $height * $ratio_orig;
    } 
    // resize to width (orig is landscape)
    else {
        $height = $width / $ratio_orig;
    }

    // Temporarily increase the memory limit to allow for larger images
    ini_set('memory_limit', '32M'); 

    switch ($type) 
    {
        case IMAGETYPE_GIF: 
            $image = imagecreatefromgif($srcFile); 
            break;   
        case IMAGETYPE_JPEG:  
            $image = imagecreatefromjpeg($srcFile); 
            break;   
        case IMAGETYPE_PNG:  
            $image = imagecreatefrompng($srcFile);
            break; 
        default:
            throw new Exception('Unrecognized image type ' . $type);
    }

    // create a new blank image
    $newImage = imagecreatetruecolor($width, $height);

    // Copy the old image to the new image
    imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

    // Output to a temp file
    $destFile = tempnam();
    imagepng($newImage, $destFile);  

    // Free memory                           
    imagedestroy($newImage);

    if ( is_file($destFile) ) {
        $f = fopen($destFile, 'rb');   
        $data = fread($f);       
        fclose($f);

        // Remove the tempfile
        unlink($destFile);    
        return $data;
    }

    throw new Exception('Image conversion failed.');
}
6 голосов
/ 22 августа 2008

Ваши шаги процесса должны выглядеть следующим образом:

  1. Проверка тип файла
  2. Загрузить изображение, если это поддерживаемый тип файла, в GD, используя imagecreatefrom *
  3. Изменение размера с использованием imagecopyresize или imagecopyresampled
  4. Сохраните изображение, используя imagepng ($ handle, 'filename.png', $ quality, $ filters)

ImageMagick работает быстрее, генерирует более качественные изображения, более настраиваем, и, наконец, (IMO) намного проще для кодирования.

@ ceejayoz Просто дождитесь нового GD - это ООП, как MySQLi, и на самом деле это неплохо:)

3 голосов
/ 22 августа 2008

Что-то вроде этого, возможно:


<?php
   //Input file
   $file = "myImage.png";
   $img = ImageCreateFromPNG($file);

   //Dimensions
   $width = imagesx($img);
   $height = imagesy($img);
   $max_width = 300;
   $max_height = 300;
   $percentage = 1;

   //Image scaling calculations
   if ( $width > $max_width ) { 
      $percentage = ($height / ($width / $max_width)) > $max_height ?
           $height / $max_height :
           $width / $max_width;
   }
   elseif ( $height > $max_height) {
      $percentage = ($width / ($height / $max_height)) > $max_width ? 
           $width / $max_width :
           $height / $max_height;
   }
   $new_width = $width / $percentage;
   $new_height = $height / $percentage;

   //scaled image
   $out = imagecreatetruecolor($new_width, $new_height);
   imagecopyresampled($out, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

   //output image
   imagepng($out);
?>

Я не тестировал код, поэтому могут быть некоторые синтаксические ошибки, однако он должен дать вам четкое представление о том, как это можно сделать. Кроме того, я принял файл PNG. Возможно, вы захотите использовать какой-то оператор switch для определения типа файла.

3 голосов
/ 22 августа 2008

Вы уверены, что на сервере нет ImageMagick?

Я приглашаю вас использовать PHP (вопрос помечен с помощью PHP). В хостинговой компании, которую я использую, расширение ImageMagick не включается в соответствии с phpinfo ().

Но когда я спросил их о том, что они ответили , вот список программ ImageMagick, доступных из кода PHP . Итак, просто - в PHP нет IM-интерфейса, но я могу вызывать IM-программы напрямую из PHP.

Надеюсь, у вас есть такая же опция.

И я решительно согласен - хранение изображений в базе данных не очень хорошая идея.

3 голосов
/ 22 августа 2008

Если вы хотите использовать gdlib, используйте gdlib 2 или выше. Он имеет функцию imagecopyresampled (), которая будет интерполировать пиксели при изменении размера и выглядеть намного лучше.

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

  • Доступ к нему медленнее, чем к диску
  • Вашему серверу нужно будет запустить скрипт, чтобы получить изображение просто подать файл
  • Ваш скрипт теперь отвечает за множество вещей, используемых веб-сервером. обрабатывать:
    • Установка правильного заголовка Content-Type
    • Установка правильных заголовков кэширования / тайм-аута / электронного тега, чтобы клиенты могли правильно кэшировать изображение. Если этого не сделать правильно, скрипт обработки изображений будет выполняться при каждом запросе, что еще больше увеличивает нагрузку на сервер.

Единственное преимущество, которое я вижу, это то, что вам не нужно синхронизировать базу данных и файлы изображений. Я все еще рекомендовал бы против этого все же.

0 голосов
/ 04 сентября 2008

phpThumb - абстракция высокого уровня, на которую стоит обратить внимание.

0 голосов
/ 22 августа 2008

Я думаю эта страница является хорошей отправной точкой. Он использует imagecreatefrom (jpeg / gif / png) и изменяет размеры и преобразует изображение, а затем выводит его в браузер. Вместо того, чтобы выводить браузер, вы можете вывести на BLOB-объект в БД без большого количества минут переписывания кода.

0 голосов
/ 22 августа 2008

Является ли GD абсолютно необходимым? ImageMagick быстрее, генерирует лучшие изображения, более конфигурируем и, наконец, (IMO) гораздо проще для кодирования.

0 голосов
/ 22 августа 2008

Эта статья выглядит так, как будто она соответствует вашим желаниям. Вам нужно изменить функцию сохранения imagejpeg () на imagepng () и попросить сохранить файл в виде строки, а не выводить его на страницу, но в противном случае его будет легко скопировать / вставить в существующий код.

...