Выбор миниатюры с внешней ссылки

Я пытаюсь создать сценарий, который извлекает список миниатюр с внешней ссылки, как это делает Facebook, когда вы делитесь ссылкой и можете выбрать изображение миниатюр, связанное с этим сообщением.

В настоящее время мой скрипт работает следующим образом:

  • file_get_contents по URL-адресу
  • preg_match_all для соответствия любому <img src="" в содержимом
  • Выполняет полный URL-адрес для каждого изображения и сохраняет его в массиве
  • Если есть <10 изображений, он проходит через и использует getimagesize для поиска ширины и высоты
  • Если есть> 10 изображений, то они прокручиваются и используют fread и imagecreatefromstring для поиска ширины и высоты (для скорости)
  • После того, как все ширина и высота будут обработаны, он будет проходить и добавляет изображения в новый массив с минимальной шириной и высотой (поэтому отображаются только более крупные изображения, меньшие изображения с меньшей вероятностью описывают URL-адрес)
  • Каждое изображение имеет свои новые размеры (сокращено пропорционально) и возвращается …

<img src="'.$image[0].'" width="'.$image[1].'" height="'.$image[2].'"><br><br>

На данный момент это работает нормально, но есть ряд проблем, которые я могу потенциально иметь:

  1. SPEED! Если URL-адрес содержит много изображений на странице, для обработки потребуется значительно больше времени.
  2. ПАМЯТЬ! Использование getimagesize или fread & imagecreatefromstring сохранит все изображение в памяти, любые большие изображения на странице могут съесть память сервера и убить мой скрипт (и сервер)

Одно из решений, которое я нашел, – это возможность получить ширину и высоту изображения из заголовка изображения без необходимости загрузки всего изображения, хотя я нашел только код для этого для JPG (ему нужно будет поддерживать GIF и PNG ).

Может ли кто-нибудь сделать какие-либо предложения, чтобы помочь мне с любой проблемой, упомянутой выше, или, возможно, вы можете предложить другой способ сделать это. Я открыт для идей … Спасибо!

** Изменить: Код ниже:

 // Example images array $images = array('http://img.ruphp.com/image-processing/1.jpg', 'http://img.ruphp.com/image-processing/2.jpg'); // Find the image sizes $image_sizes = $this->image_sizes($images); // Find the images that meet the minimum size for ($i = 0; $i < count($image_sizes); $i++) { if ($image_sizes[$i][0] >= $min || $image_sizes[$i][1] >= $min) { // Scale down the original image size $dimensions = $this->resize_dimensions($scale_width, $scale_height, $image_sizes[$i][0], $image_sizes[$i][1]); $img[] = array($images[$i], $dimensions['width'], $dimensions['height']); } } // Output the images foreach ($img as $image) echo '<img src="'.$image[0].'" width="'.$image[1].'" height="'.$image[2].'"><br><br>'; /** * Retrieves the image sizes * Uses the getimagesize() function or the filesystem for speed increases */ public function image_sizes($images) { $out = array(); if (count($images) < 10) { foreach ($images as $image) { list($width, $height) = @getimagesize($image); if (is_numeric($width) && is_numeric($height)) { $out[] = array($width, $height); } else { $out[] = array(0, 0); } } } else { foreach ($images as $image) { $handle = @fopen($image, "rb"); $contents = ""; if ($handle) { while(true) { $data = fread($handle, 8192); if (strlen($data) == 0) break; $contents .= $data; } fclose($handle); $im = @imagecreatefromstring($contents); if ($im) { $out[] = array(imagesx($im), imagesy($im)); } else { $out[] = array(0, 0); } @imagedestroy($im); } else { $out[] = array(0, 0); } } } return $out; } /** * Calculates restricted dimensions with a maximum of $goal_width by $goal_height */ public function resize_dimensions($goal_width, $goal_height, $width, $height) { $return = array('width' => $width, 'height' => $height); // If the ratio > goal ratio and the width > goal width resize down to goal width if ($width/$height > $goal_width/$goal_height && $width > $goal_width) { $return['width'] = floor($goal_width); $return['height'] = floor($goal_width/$width * $height); } // Otherwise, if the height > goal, resize down to goal height else if ($height > $goal_height) { $return['width'] = floor($goal_height/$height * $width); $return['height'] = floor($goal_height); } return $return; } 

getimagesize читает только заголовок, но imagecreatefromstring считывает целое изображение. Изображение, прочитанное GD, ImageMagick или GraphicsMagic хранится в виде растрового изображения, поэтому оно потребляет ширину (3 или 4) байта, и вы ничего не можете с этим поделать. Лучшим решением для вашей проблемы является создание многослогового завитка (см. http://ru.php.net/manual/en/function.curl-multi-select.php ), а затем один за другим обрабатываются изображения с GD или любой другой библиотеки. И чтобы потребление памяти было немного ниже, вы можете хранить файлы изображений на диске, а не в памяти.

Единственная идея, которая приходит на ум для вашего текущего подхода (что впечатляет), – это проверить HTML для существующих атрибутов ширины и высоты и вообще пропустить процесс чтения файлов, если они существуют.