Как изменить размер и преобразовать загруженное изображение в PNG с помощью GD?

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

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

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

22.08.2008 12:53:54
Не обслуживайте и не храните изображения из или в БД.
dlamblin 30.10.2009 07:11:12
9 ОТВЕТОВ
РЕШЕНИЕ
<?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.');
}
24
22.08.2008 13:49:01
Спасибо за это решение! :) Он даже работает с частично прозрачными фотографиями (это была моя первоначальная проблема)!
bastiandoeen 19.11.2008 15:22:25

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

0
22.08.2008 12:57:24

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

1
22.08.2008 12:58:51
Звучит, но простой рекламный ролик. Есть доказательства?
Green 19.08.2012 22:56:25
Конечно. Чтобы сделать обрезанное изображение: $image = new Imagick($image_path); $image->cropThumbnailImage(100,100);попробуйте сделать это в GD в две строки кода. ImageMagick - это инструментарий, разработанный специально для работы с изображениями, поэтому он обычно будет лучше, чем случайная добавленная часть PHP.
ceejayoz 20.08.2012 01:05:46

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

0
22.08.2008 12:58:54

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

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

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

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

3
22.08.2008 13:07:29
Это определенно плохо для обслуживания изображений из БД по сравнению с разгрузкой их на их собственный легкий статический сервер в статическом домене или cdn.
dlamblin 30.10.2009 07:10:07

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

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

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

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

6
22.08.2008 13:30:53

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

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

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

Я надеюсь, что у вас есть такой же вариант.

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

3
22.08.2008 13:23:32

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


<?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.08.2008 13:26:06

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

0
4.09.2008 14:12:13