2010-02-12 3 views
3

Я пытаюсь создать скрипт, который извлекает список миниатюр с внешней ссылки, как это делает 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).

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

** Edit: Код ниже:

// Example images array 
$images = array('http://blah.com/1.jpg', 'http://blah.com/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; 
} 
+0

Опубликуйте код, и мы посмотрим, что мы можем сделать! – mattbasta

+0

Ok отредактирован! – fire

+0

Используете ли вы этот скрипт в подобной среде, где вы должны вернуть мгновенную информацию браузеру? Или весь процесс может работать позже? –

ответ

1

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

+0

спасибо, я дам ему пойти .. – fire

0

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

+0

Да, я рассмотрел это, но большинство сайтов не беспокоят атрибуты ширины и высоты, также вы можете иметь изображение 1px x 10px и растягивать ширину до 800 пикселей для создания строки (старая школа, которую я знаю, но люди все еще это делают), которая мой скрипт будет рассматривать как допустимое изображение, соответствующее минимальным требованиям к ширине! – fire

+0

Очень верно. Возможно, этот метод позволит вам отсеивать изображения, которые не отвечают минимальным требованиям. Я сейчас нахожусь в тупике для других идей, +1 к надежде получить некоторую тягу. – nortron

Смежные вопросы