Все наверное уже видели этот шэдевральный комикс от xkcd. А тем кто не видел — очень рекомендую посмотреть.
Ну так вот. Интересно мне было посмотреть как он выглядит целиком. И вот если бы я сначала подумал, а не сразу принялся бы код, то понял бы, что это бессмысленно. т.к. общий размер изображения 13+ ГИГАПИКСЕЛЕЙ. А моим вьювером, как выяснилось больше 0.6 ГП не открывается. Да и библиотека с изображениями, размер которых по одному из измерений больше 33 КП, работает нестабильно. Но зато я хоть немножко познакомился с GD.
Склеить получилось(нормально склеилось и нормально смотрелось) участок вот такого размера:
Полная же картинка выглядит так:
Второе изображение отсюда.
upd. На хабре узнал про скрол версию.
Для склейки изображений я набрасал простенький скрипт, код которого приведён далее.
К сожалению он умеет склеивать изображения только начиная от центра.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
#!/usr/local/bin/perl use GD; my $maxs = 1; #down my $maxn = 9; #up my $maxe = 8; #right my $maxw = 8; #left my $maxy = 2048*($maxn+$maxs); my $maxx = 2048*($maxe+$maxw); my $im = new GD::Image($maxx, $maxy); my $white = $im->colorAllocate(255, 255, 255); my $black = $im->colorAllocate(0, 0, 0); #nw for my $n (1..$maxn){ for my $w (1..$maxw){ my $filename = "${n}n${w}w.png"; next unless -e $filename; my $src = newFromPng GD::Image($filename); my ($x, $y) = (2048*($maxw - $w), 2048*($maxn-$n)); $im->copy($src, $x, $y, 0, 0, 2048, 2048); } } #ne for my $n (1..$maxn){ for my $e (1..$maxe){ my $filename = "${n}n${e}e.png"; next unless -e $filename; my $src = newFromPng GD::Image($filename); my ($x, $y) = (2048*($maxe+$e-1), 2048*($maxn-$n)); $im->copy($src, $x, $y, 0, 0, 2048, 2048); } } #sw for my $s (1..$maxs){ for my $w (1..$maxw){ my $filename = "${s}s${w}w.png"; my ($x, $y) = (2048*($maxw - $w), 2048*($maxn+$s-1)); unless( -e $filename){ $im->filledRectangle($x,$y,$x+2048,$y+2048,$black); } else{ my $src = newFromPng GD::Image($filename); $im->copy($src, $x, $y, 0, 0, 2048, 2048); } } } #se for my $s (1..$maxs){ for my $e (1..$maxe){ my $filename = "${s}s${e}e.png"; my ($x, $y) = (2048*($maxe+$e-1), 2048*($maxn+$s-1)); unless( -e $filename){ $im->filledRectangle($x,$y,$x+2048,$y+2048,$black); } else{ my $src = newFromPng GD::Image($filename); $im->copy($src, $x, $y, 0, 0, 2048, 2048); } } } binmode STDOUT; print $im->png(9); |
Запуск и измерение времени работы:
1 2 3 4 5 |
$ time ./glue.pl > im.png real 0m15.085s user 0m14.730s sys 0m0.300s |
для 600’000’000 пикселей и высокой библиотеки вполне неплохо.
То что получилось. Осторожно, экран ещё разорвёт ;-) А если серьёзно, не везде открывается.
Каких либо важных выводов пока из этого не вынес, но меня порадовало то, что с помощью библиотечки для пёрла можно работать даже с теми картинками, которые не каждому нативному приложению для работы с графикой под силу.