SleepShadowWeb
24.05.2010, 05:29
Задача:
получить изображение всей карты нужного масштаба с сайта www.map.bryandex.ru (берём масштаб = 4)
Реализация:
запускаем сайт в Mozilla Firefox и включаем Firebug, в панели "Сценарий" должно быть отмечено галочкой "Декомпилировать исходники eval"
смотрим исходный код сайта, переходим на страницу, куда ведёт iframe.
из анализа кода:
36 - количество мини-картинок по ширине
24 - количество мини-картинок по высоте
256 - ширина и высота мини-картинки
'map' + scale + '/' + getimg(i, j) + '.gif' - путь к нашим картинкам
исходный, декомпилированный код функции getimg(i, j) находим в панели "Сценарий".
поскольку используется прямой путь к файлу-изображению, а не через скрипт, то остаётся убедиться, что нет других препятствий.
теперь проверим есть ли ограничения в файле .htaccess на использование картинок другими хостами - ограничений нет.
(просто разместить html код у себя на сервере <img src='http://www.map.bryandex.ru/map4/AAGDCGAGCHI.gif'>)
название картинки получаем с помощью Firebug.
вся необходимая информация получена.
Продолжаем:
для начала скачаем все мини-картинки к себе. конвертируем функцию getimg из JavaScript в PHP.
щедро раздаём каждой переменной по "баксу", и заменяем функции на аналоги.
function getimg($y, $x)
{
$xx = $x * 648 - 130 + $y;
$yy = $y * 512 - 60 + $x;
$imgstr = $yy . "7" . $xx;
$imgstr1 = "";
for ($i = 0; $i < strlen($imgstr); $i++)
{
$char = substr($imgstr, $i, 1);
switch ($char)
{
case "1":
$imgstr1 .= "A";
break;
case "2":
$imgstr1 .= "B";
break;
case "3":
$imgstr1 .= "C";
break;
case "4":
$imgstr1 .= "D";
break;
case "5":
$imgstr1 .= "E";
break;
case "6":
$imgstr1 .= "F";
break;
case "7":
$imgstr1 .= "G";
break;
case "8":
$imgstr1 .= "H";
break;
case "9":
$imgstr1 .= "I";
break;
case "0":
$imgstr1 .= "O";
break;
default:;
}
}
return $imgstr1;
}
кусочек по скачиванию картинок (вариант 1):
производительно выгоднее чем "вариант 2", поскольку использует 'memory mapping'
-------------------------------------------
set_time_limit(0);
for($j = 1; $j <= 24; $j++)
for($i = 1; $i <= 36; $i++)
{
$name = getimg($j, $i).".gif";
$data_file = '';
$data_file = @file_get_contents("http://www.map.bryandex.ru/map4/".$name); // файл с указанным именем может не существовать (добавил @)
if($data_file) file_put_contents("pic/".$name, $data_file); // сохраняем с тем же именем к себе в папочку "pic"
}
кусочек по скачиванию картинок (вариант 2):
-------------------------------------------
set_time_limit(0);
for($j = 1; $j <= 24; $j++)
for($i = 1; $i <= 36; $i++)
{
$name = getimg($j, $i).".gif";
$buffer = "";
$handle = @fopen("http://www.map.bryandex.ru/map4/".$name, "rb");
if(!$handle) continue;
while (!feof($handle)) {
$buffer .= fgets($handle, 4096);
}
fclose($handle);
$handle = fopen("pic/".$name, "wb");
fwrite($handle, $buffer);
fclose($handle);
}
картинки уже скачаны и находятся у нас в папочке "pic" (получилось 798 штук, занимают 4494 Кб).
приступаем к склейке в одно большое изображение:
set_time_limit(0); // не будем себя ограничивать по времени
$w = 256; // ширина мини-картинки
$h = 256; // высота мини-картинки
$kol_w = 36; // количество мини-картинок по ширине
$kol_h = 24; // количество мини-картинок по высоте
$all_w = $kol_w * $w; // подсчитываем ширину результирующего изображения
$all_h = $kol_h * $h; // подсчитываем высоту результирующего изображения
$im = imagecreatetruecolor($all_w, $all_h); // создаём изображение нужных размеров
imagefill($im, 0, 0, "#000000"); // заливаем созданное изображение чёрным цветом (это так - для кучи, т.к. при создании изображения строкой выше - оно и так чёрное)
for($i = 1; $i <= $kol_h; $i++)
for($j = 1; $j <= $kol_w; $j++)
{
$name = "pic/".getimg($i, $j).".gif";
// ещё на этапе скачивания файлов с сайта выяснилось, что не все они там есть (т.е. карта с "дырами"). вот и приходится это контролировать
if(!is_file($name)) $name = 'blank.gif';
// если файл с нужным именем не существует, то заменяю его на собственную картинку (размером $W x $H px) с нарисованными диагоналями на однотонном фоне
// как вариант можно и ничего в этом случае не делать, а просто пропустить выполнение следующих трёх строк, тогда пропущенный участок будет цветом фона
@$im_1 = imagecreatefromgif($name);
imagecopyresampled($im, $im_1, ($j - 1) * $w, ($i - 1) * $h, 0, 0, $w, $h, $w, $h);
imageDestroy($im_1);
}
imageJpeg($im, 'image_ready.jpg'); // записываем полученное изображение в файл
imageDestroy($im);
небольшой нюанс: всё это дело по созданию большой картинки занимает много памяти, вот поэтому нужно в файл php.ini внести некоторые коррективы.
к примеру, вот так:
memory_limit = 999999M;
результатом всех этих действий получился файл-изображение "image_ready.jpg" весом 4524 Кб и габаритами 9216 х 6144 px
всё получилось, а дальше можно и в типографию отправлять...
получить изображение всей карты нужного масштаба с сайта www.map.bryandex.ru (берём масштаб = 4)
Реализация:
запускаем сайт в Mozilla Firefox и включаем Firebug, в панели "Сценарий" должно быть отмечено галочкой "Декомпилировать исходники eval"
смотрим исходный код сайта, переходим на страницу, куда ведёт iframe.
из анализа кода:
36 - количество мини-картинок по ширине
24 - количество мини-картинок по высоте
256 - ширина и высота мини-картинки
'map' + scale + '/' + getimg(i, j) + '.gif' - путь к нашим картинкам
исходный, декомпилированный код функции getimg(i, j) находим в панели "Сценарий".
поскольку используется прямой путь к файлу-изображению, а не через скрипт, то остаётся убедиться, что нет других препятствий.
теперь проверим есть ли ограничения в файле .htaccess на использование картинок другими хостами - ограничений нет.
(просто разместить html код у себя на сервере <img src='http://www.map.bryandex.ru/map4/AAGDCGAGCHI.gif'>)
название картинки получаем с помощью Firebug.
вся необходимая информация получена.
Продолжаем:
для начала скачаем все мини-картинки к себе. конвертируем функцию getimg из JavaScript в PHP.
щедро раздаём каждой переменной по "баксу", и заменяем функции на аналоги.
function getimg($y, $x)
{
$xx = $x * 648 - 130 + $y;
$yy = $y * 512 - 60 + $x;
$imgstr = $yy . "7" . $xx;
$imgstr1 = "";
for ($i = 0; $i < strlen($imgstr); $i++)
{
$char = substr($imgstr, $i, 1);
switch ($char)
{
case "1":
$imgstr1 .= "A";
break;
case "2":
$imgstr1 .= "B";
break;
case "3":
$imgstr1 .= "C";
break;
case "4":
$imgstr1 .= "D";
break;
case "5":
$imgstr1 .= "E";
break;
case "6":
$imgstr1 .= "F";
break;
case "7":
$imgstr1 .= "G";
break;
case "8":
$imgstr1 .= "H";
break;
case "9":
$imgstr1 .= "I";
break;
case "0":
$imgstr1 .= "O";
break;
default:;
}
}
return $imgstr1;
}
кусочек по скачиванию картинок (вариант 1):
производительно выгоднее чем "вариант 2", поскольку использует 'memory mapping'
-------------------------------------------
set_time_limit(0);
for($j = 1; $j <= 24; $j++)
for($i = 1; $i <= 36; $i++)
{
$name = getimg($j, $i).".gif";
$data_file = '';
$data_file = @file_get_contents("http://www.map.bryandex.ru/map4/".$name); // файл с указанным именем может не существовать (добавил @)
if($data_file) file_put_contents("pic/".$name, $data_file); // сохраняем с тем же именем к себе в папочку "pic"
}
кусочек по скачиванию картинок (вариант 2):
-------------------------------------------
set_time_limit(0);
for($j = 1; $j <= 24; $j++)
for($i = 1; $i <= 36; $i++)
{
$name = getimg($j, $i).".gif";
$buffer = "";
$handle = @fopen("http://www.map.bryandex.ru/map4/".$name, "rb");
if(!$handle) continue;
while (!feof($handle)) {
$buffer .= fgets($handle, 4096);
}
fclose($handle);
$handle = fopen("pic/".$name, "wb");
fwrite($handle, $buffer);
fclose($handle);
}
картинки уже скачаны и находятся у нас в папочке "pic" (получилось 798 штук, занимают 4494 Кб).
приступаем к склейке в одно большое изображение:
set_time_limit(0); // не будем себя ограничивать по времени
$w = 256; // ширина мини-картинки
$h = 256; // высота мини-картинки
$kol_w = 36; // количество мини-картинок по ширине
$kol_h = 24; // количество мини-картинок по высоте
$all_w = $kol_w * $w; // подсчитываем ширину результирующего изображения
$all_h = $kol_h * $h; // подсчитываем высоту результирующего изображения
$im = imagecreatetruecolor($all_w, $all_h); // создаём изображение нужных размеров
imagefill($im, 0, 0, "#000000"); // заливаем созданное изображение чёрным цветом (это так - для кучи, т.к. при создании изображения строкой выше - оно и так чёрное)
for($i = 1; $i <= $kol_h; $i++)
for($j = 1; $j <= $kol_w; $j++)
{
$name = "pic/".getimg($i, $j).".gif";
// ещё на этапе скачивания файлов с сайта выяснилось, что не все они там есть (т.е. карта с "дырами"). вот и приходится это контролировать
if(!is_file($name)) $name = 'blank.gif';
// если файл с нужным именем не существует, то заменяю его на собственную картинку (размером $W x $H px) с нарисованными диагоналями на однотонном фоне
// как вариант можно и ничего в этом случае не делать, а просто пропустить выполнение следующих трёх строк, тогда пропущенный участок будет цветом фона
@$im_1 = imagecreatefromgif($name);
imagecopyresampled($im, $im_1, ($j - 1) * $w, ($i - 1) * $h, 0, 0, $w, $h, $w, $h);
imageDestroy($im_1);
}
imageJpeg($im, 'image_ready.jpg'); // записываем полученное изображение в файл
imageDestroy($im);
небольшой нюанс: всё это дело по созданию большой картинки занимает много памяти, вот поэтому нужно в файл php.ini внести некоторые коррективы.
к примеру, вот так:
memory_limit = 999999M;
результатом всех этих действий получился файл-изображение "image_ready.jpg" весом 4524 Кб и габаритами 9216 х 6144 px
всё получилось, а дальше можно и в типографию отправлять...