Пользователь
0,0
рейтинг
26 июня 2009 в 03:44

Разработка → Делаем скриншоты сайтов

PHP*
Бродя по просторам PHP документации случайно наткнулся на две функции: imagegrabwindow и imagegrabscreen. Они умеют делать скриншоты в Microsoft Windows.
Заинтересовало. Кончилось дело тем, что был написан скриптик генерирующий полный скриншот любого сайта.
Итак нам необходимы:


В функции imagegrabwindow дан неплохой пример по использованию.
$browser = new COM("InternetExplorer.Application");
$handle = $browser->HWND;
$browser->Visible = true;
$browser->Navigate("http://www.libgd.org");

/* Still working? */
while ($browser->Busy) {
  com_message_pump(4000);
}
$im = imagegrabwindow($handle, 0);
$browser->Quit();
imagepng($im, "iesnap.png");
imagedestroy($im);


* This source code was highlighted with Source Code Highlighter.


Но он обладает большим недостатком — какого размера открылось окошко браузера, такой мы и получим скриншот.
Дабы исправить это пришлось написать скрипт, который дополнительно делает следующие вещи:
  • Раскрывает окно браузера на весь экран в полноэкранном режиме
  • Отключает полосу состояния
  • Затирает скроллинг
  • Делает необходимое число скриншотов страницы с помощью прокрутки страницы и объединяет их

Кодяра


<?php
$browser = new COM("InternetExplorer.Application");
$browser->Visible = true;
$browser->Fullscreen = true;
$browser->StatusBar = false;

$browser->Navigate("http://www.habrahabr.ru");
while ($browser->Busy)
  com_message_pump(4000);

$handle = $browser->HWND;  
$screenWidth = $browser->Width;
$screenHeight = $browser->Height;
$documentHeight = $browser->Document->body->scrollHeight;

$scrollWidth = 20;
$scrollHeight = 20;
$testPartSize = 10*1024;

$im = imagecreatetruecolor($screenWidth - $scrollWidth, $documentHeight);
for($top = 0; $top < $documentHeight; $top += $screenHeight)
{
 $browser->Document->documentElement->scrollTop=$top;
 while ($browser->Busy)
  com_message_pump(4000);
 echo $browser->Document->documentElement->scrollTop.PHP_EOL;
 
 for($i = 0; $i < 5; $i++)
 {
  $part = imagegrabwindow($handle, 0);
  $dark = imagecolorallocate($part, 0, 0, 0);
  imagefilledrectangle($part, $screenWidth - $scrollWidth, 0, $screenWidth, $screenHeight, $dark);
  $testFile = sprintf("screenshot_%05d.png", $top);
  imagepng($part, $testFile, 9, PNG_ALL_FILTERS);
  clearstatcache();
  if(filesize($testFile) > $testPartSize)
   break;
   
  echo "Bad part, name: {$testFile}, try to generate again.".PHP_EOL;
 } 
 
 imagecopy(
  $im, $part,
  0, $top,
  0, (!$top || ($top + $screenHeight) < $documentHeight) ? 0 : $screenHeight - $scrollHeight - $documentHeight % $screenHeight,
  $screenWidth - $scrollWidth, $screenHeight);  
 imagedestroy($part);  
}
imagepng($im, "screenshot.png", 9, PNG_ALL_FILTERS);
imagedestroy($im);

$browser->Quit();

* This source code was highlighted with Source Code Highlighter.


Замечания к коду

  • Иногда по непонятным причинам делается скриншот, а там чёрный экран, дабы устранить это делается запись снятого куска в файл с затёртым скроллингом, а затем проверяется размер файла. Если файл мал, скорее всего надо переснять.
  • При желании быстро протестить, можно воспользоваться следующем командной строкой:
    php -d extension_dir=c:\php\ext\ -d extension=php_gd2.dll ie.php
    где ie.php — скрипт выше.
  • Можно из под апача запускать, но для этого надо менять настройки безопасности. В документации к этим функциям написано что делать.


А как в других браузерах


Для FireFox нашёл Embedded Mozilla раздел, к сожалению требует кодирования, но при написании полноценного сервиса получится гораздо эффективнее.
UPD: Читайте коменты, там находится много ссылок того, как это делать на других движках и в других системах.

P.S. Проверено только в виртуалке на IE7.
P.S. Сам IE ненавижу, использую FireFox.
Андрей Нехайчик @gnomeby
карма
43,2
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (63)

  • +5
    хм интерестно а как бы под никсой и без окон сделать…
    • +6
      Вам поможет Xvfb. А в разделе внешних ссылок внизу страницы искомый линк :)
      • +2
        О спс!
      • 0
        Спасибо :)
      • –1
        Оффтопик конечно но может вы подскажите нельзя ли как то получить у FF доступ к DOM дереву после рендера страницы?
  • –21
    какого размеро открылось окошко


    исправте
    • +29
      исправте
      исправьте
      • +1
        спасибо за исправление.

        если б имел такую возможность — исправил бы
    • 0
      надеюсь минусуют те, кто сам никогда ошибок не делает
      • +2
        Ошибка и опечатка — это две большие разницы (ц)
      • –1
        Или те, кто делают, но не учат грамотности других :)
    • 0
      советую всем поставить проверку правописания в Вашем любимом браузере, что бы не пришлось указывать на ошибки.
      вот несколько ссылок:
      для Firefox
      для Opera
      для других, думаю, Вы и сами найдете.
      • 0
        Проверка правописания не помогла вам написать слово «чтобы» правильно.
        • 0
          виноват. но при орфорграфических ошибках spell checker помогает, вообщем на что он и расчитан.
          • 0
            В русском языке нет слова «вообщем», spell checker и тут бессилен. В русском языке существует наречие «вообще» и словосочетание «в общем»
  • 0
    Да здравствует снова параноя(!)
    а ведь считал что избавился уже))
    • +4
      ОМГ))) не в тот топик ушло))) извиняюсь))
  • +2
    а как насчет времени? сколько секунд уходит ( в среднем ) на создание скрина?
    • +1
      Опробовал скрипт автора, всё работает, на моей машине скрины делаются от 10 до 15 секунд. Тестировал на ие6. Заметил, что во время построения рисунка мой пхп съедаел от 60 до 80 % cpu, что весьма и весьма печально, хотя процессор и не самый слабый. И ещё почему-то не работает $browser->Quit();.
      • 0
        В скрипте идёт очень сильная упаковка в PNG, этим можно порулить и снизить нагрузку. Правда и файлы на выходе получатся больше.
  • 0
    Осталось написать скрипт, который будет выдирать из страницы текст с картинками и сохранять в удобном варианте (pdf).
    • 0
      Библеотека PDF вам в помощь!!! Из скриншота конвертнуть не проблема!!!
      • –1
        Текст из скриншота? 0_0
        • 0
          Tesseract :)
  • НЛО прилетело и опубликовало эту надпись здесь
  • –7
    > Они умеют делать скриншоты в Microsoft Windows

    мда… лучшебы они делали в UNIX консоле без GUI, тогдабы было супер, а так совершенно бесполезная вещь
  • +3
    мы в работе используем вот это: www.betalon.com/blog/server/create-your-own-website-screenshot-server.htm
    работает в любой операционной системе где есть Firefox 3
    • –1
      А где ни есть ФФ

      С админом отношения хорошие но он ни за что на сервер ни поставит такого рода приложения )
    • 0
      Не слишком хорошо работает.
      Поставил это все дело на не очень свежем ноуте под убунтой. Тестил с удаленных машин. По одному скриншоту делает нормально, только если сайт тяжелый и подгружается долго, то можно не дождаться скриншота. Вот например thg.ru у меня так и не показался.
      Если запустить несколько параллельных запросов, то начинает чудить. То по одному запросу отдаст чужой скрин, то вкладки пустые оставляет, то предлагает скачать файл нулевого размера.
  • 0
    Следующий шаг кросплатформенное решение
    • 0
      мой линк выше -)
  • +5
    P.S. Сам IE ненавижу, использую FireFox.

    Как это связано с темой статьи (тем более при использовании com-объекта IE)?
    • +4
      Это для предотвращения коментариев типа:
      * Опять это говно…
      * Ну вы и выбрали браузер.
  • +3
    в тему PS статьи:
    sсreengrub? https://addons.mozilla.org/en-US/firefox/addon/1146 хочешь всю, хочешь видимое, хочешь кастом…
    • +1
      Да и в продолжение FireShot (для IE и FF)
  • +1
    А чем не устраивает BrowserShots?
    • 0
      Я думаю, что для каких-то более простых задач это слишком «тяжеловесный» сервис. Когда надо сделать скриншот одним браузером и быстро то лучше что-то по-проще использовать.
  • +1
    Злой дядя может попросить ваш скрипт сделать скирншот его странички с IE-сплоитом ]:->
    • 0
      Кстати да, если кто-нибудь захочет сделать по-быструхе сервис для внутренних целей, ему стоит задкматься об этом.
  • –1
    Спасибо автору, полезные вещи.
    • –2
      Уже спасибо сказать нельзя? Блять… Как заебало это мудоёбство, когда минусы ставят от нехуй делать. Ничего бля. Я с Денискиным за это пообщаюсь.
      • 0
        Ну так и говорите это автору. А здесь обсуждение.
  • 0
    site-shot.ru/test/ — преальфа, пребеда и т.д. Просто тупой парсинг с другого ресурса. Ничего не вводите, просто нажмите на Shot, появится страничка яшы. Поможите мальчику доделать :)
    • 0
      Беда?
      • 0
        Что-то вроде того. Отсутствие достаточных знаний, которые необходимо пополнять.
        • 0
          Что-то оно совсем того…
          • 0
            Завтра попробуйте, не вы первый видать, резанули меня :)
  • +1
    Осилит habrahabr.ru/blogs/design/61792/ — Групповой Pixel Art
    • 0
      153 секунды, файл на выходе — 5.8 Миб.

      Правда пришлось допилить. Вместо:
      $browser->Document->documentElement->scrollTop=$top;
      нужно
      $browser->Document->body->scrollTop=$top;
      Строчка запуска:
      php -d extension_dir=c:\php\ext\ -d extension=php_gd2.dll -d memory_limit=400M ie.php
      Ну и конечно поколдовать со значениями высоты скролинга.
      • 0
        Неужто memory limit до конца выжирает? O_o
        • 0
          256 мне не хватило
          • 0
            Ничего себе.
            • 0
              Нормально, скриншот того сайта 1000x35000, что в неупакованном виде для RGB 115 Мб + сборщик мусора не оперативен + кусок с текущим окном + расход памяти при упаковке. 128 Хватает только чтобы создать пустую картинку RGB 1000x35000.
  • 0
    Есть вопросик к спецам по COM-интерфейсу IE. Напишите в личку, кому интересно.
    • +1
      Уверен вы просто заинтриговали всех спецов.)
    • 0
      Пиши тут, коллективный разум решает…
  • 0
    Кстати, могу поделиться перловым аналогом — Win32-CaptureIE-1.30 Делает вполне приличные скрины даже при 1600Х1200. Я так за Яндекс.Пробками наблюдаю.
  • +1
    Мсье знает толк в извращениях.
    Пользуюсь browsershots.org/ и Вам рекомендую.
    • +1
      Кстати, спасибо за код. Навел на кое-какие мысли.
      • +1
        Будьте осторожны, это уголовно наказуемо.
  • 0
    Могу поделиться аналогичным скриптом для *nix, если его автор — sergio — не возражает. Требует присутствия X на сервере.
  • 0
    Вы — не автор
    domaintimes.net/forum/showthread.php?p=15364
    • 0
      Даты публикации сверьте и узнаете кто автор.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.