Журнал LinuxFormat - перейти на главную

LXF134:Perl

Материал из Linuxformat
Перейти к: навигация, поиск
GD и Perl Соз­дай­те ди­на­ми­че­ские изо­бра­же­ния в ва­ших сце­на­ри­ях для Web, и не толь­ко

Содержание

Perl: Создаем изо­бра­же­ния

Perl Марко Фиоретти
Perl Ми­ха­ил Смир­нов
Часть 1: Язык, соз­дан­ный для об­ра­бот­ки тек­стов, мо­жет не­пло­хо справ­лять­ся и с гра­фи­кой. Ми­ха­ил Смир­нов объ­яс­нит, что к че­му.

Как из­вест­но, язык про­грам­ми­ро­вания Perl иде­аль­но при­спо­соб­лен для мно­го­чис­лен­ных при­ло­жений по об­ра­бот­ке тек­ста. Од­на­ко воз­мож­но­сти Perl этим не ис­чер­пы­ва­ют­ся. При­менение гра­фи­че­ских мо­ду­лей в Perl по­зво­лит вам бы­ст­ро ри­со­вать изо­бра­жения, со­стоя­щие из линий, ок­руж­но­стей и тек­ста, манипу­ли­ро­вать цве­том, вы­ре­зать и встав­лять дру­гие изо­бра­жения, вы­пол­нять за­лив­ку, со­хра­нять на диске фай­лы изо­бра­жений в раз­лич­ных фор­ма­тах, манипу­ли­ро­вать ви­део­дан­ны­ми этих фай­лов. Наи­боль­ший ин­те­рес пред­став­ля­ет ис­поль­зо­вание гра­фи­че­ских мо­ду­лей Perl в web-при­ло­жениях. Гра­фи­че­ская биб­лио­те­ка GD име­ет ин­туи­тив­но по­нят­ный ин­тер­фейс, по­зво­ляю­щий бы­ст­ро и ком­пакт­но реа­ли­зо­вать поль­зо­ва­тель­ский код про­грамм на Perl да­же на­чи­наю­щим про­грам­ми­стам.

Эф­фек­тив­ность ис­поль­зо­вания гра­фи­че­ско­го мо­ду­ля GD объ­яс­ня­ет­ся про­сто: биб­лио­те­ка GD напи­са­на на язы­ке C и со­вмести­ма со все­ми основ­ны­ми плат­фор­ма­ми (Linux, Windows, ...). Ин­тер­фейс ме­ж­ду Perl и биб­лио­те­кой GD обес­пе­чи­ва­ет мо­дуль GD.pm, ко­то­рый ис­поль­зу­ет GD как ба­зис для соз­дания гра­фи­че­ских клас­сов в Perl. GD.pm яв­ля­ет­ся са­мо­за­гру­жае­мым ин­тер­фейс­ным мо­ду­лем, с по­мо­щью ко­то­ро­го мож­но соз­да­вать изо­бра­жения на ле­ту, мо­ди­фи­ци­ро­вать су­ще­ствую­щие фай­лы изо­бра­жений и син­те­зи­ро­вать но­вые.

При­вет, GD!

Биб­лио­те­ка GD по­зво­ля­ет соз­да­вать цвет­ные ри­сун­ки, ис­поль­зуя боль­шое ко­ли­че­ство гра­фи­че­ских при­ми­ти­вов, и вы­во­дить их в раз­лич­ных гра­фи­че­ских фор­ма­тах. Мо­дуль GD оп­ре­де­ля­ет три основ­ных клас­са:

  • класс изо­бра­жений GD::Image, ко­то­рый пред­на­зна­чен для за­хва­та ви­део­дан­ных изо­бра­жения и вы­пол­ня­ет вы­зов ме­то­дов гра­фи­че­ских при­ми­ти­вов;
  • класс шриф­тов GD::Font, ко­то­рый бе­рет ста­ти­че­ские шриф­ты и ис­поль­зу­ет их для воспро­из­ве­дения тек­ста в гра­фи­че­ском ви­де;
  • класс при­ми­ти­вов по­ли­го­на GD::Polygon, при­ме­няе­мый для со­хранения спи­ска вер­шин мно­го­угольников при ри­со­вании сто­рон по­ли­го­на и обес­пе­чи­ваю­щий их воспро­из­ве­дение в ви­де изо­бра­жения.

Обоб­щен­ный под­ход ис­поль­зо­вания гра­фи­че­ско­го ин­тер­фей­са GD вы­гля­дит сле­дую­щим об­ра­зом. На пер­вом эта­пе, при вы­зо­ве (инициа­ли­за­ции) ме­то­да GD::Image::new(Wx,Hy), соз­да­ет­ся но­вое пустое изо­бра­жение, ши­ри­на и вы­со­та ко­то­ро­го за­да­ют­ся па­ра­мет­ра­ми Wx и Hy. В ре­зуль­та­те вы­зо­ва ме­то­да бу­дут воз­вра­ще­ны ви­део­дан­ные изо­бра­жения. Дру­гие ме­то­ды клас­са по­зво­ля­ют инициа­ли­зи­ро­вать изо­бра­жение из уже су­ще­ствую­щих фай­лов, ко­то­рые необ­хо­ди­мо пред­ва­ри­тель­но про­чи­тать с диска.

На вто­ром эта­пе, при вы­зо­ве ме­то­да colorAllocate() вы­пол­ня­ет­ся до­бав­ление цве­та к цве­то­вой таб­ли­це изо­бра­жения. Вход­ны­ми па­ра­мет­ра­ми вы­зо­ва яв­ля­ет­ся трой­ка основ­ных цве­тов: крас­ный, зе­ле­ный и синий, ко­то­рые за­да­ют­ся це­лы­ми чис­ла­ми в диа­па­зоне зна­чений от 0 до 255. Ме­тод воз­вра­ща­ет ин­декс цве­та цве­то­вой таб­ли­цы изо­бра­жения.

Рис. 1. Рис. 1. При­мер ри­со­ва­ния про­стых объ­ек­тов.

По­сле это­го, на треть­ем эта­пе, мож­но сде­лать неко­то­рый ри­су­нок, ис­поль­зуя на­бор гра­фи­че­ских при­ми­ти­вов клас­са GD::Image и на­бор ме­то­дов клас­са GD::Polygon. По­ли­го­ны (мно­го­угольники) соз­да­ют­ся с по­мо­щью ме­то­да new(), а до­бав­ление но­вых вер­шин по­ли­го­на воз­ло­же­но на ме­тод addPt().

И, на­конец, когда ри­су­нок го­тов, вы мо­же­те пре­об­ра­зо­вать его, на­при­мер, в гра­фи­че­ский фор­мат GIF, с по­мо­щью ме­то­да gif(). Ме­тод бу­дет воз­вра­щать дво­ич­ное со­дер­жи­мое изо­бра­жения в фор­ма­те GIF. Обыч­но по­лу­чен­ный ре­зуль­тат вы­во­дит­ся в брау­зер или со­хра­ня­ет­ся на диске в ви­де GIF-фай­ла. В ка­че­стве при­ме­ра при­ве­дем скрипт, ко­то­рый ри­су­ет про­стые фи­гу­ры, манипу­ли­ру­ет ими са­ми­ми и их цве­том, а так­же ри­су­ет текст с по­мо­щью ста­ти­че­ских шриф­тов:

 #!/perl/bin/perl
 use GD;
 $im = new GD::Image(425,250); #--Ини­циа­ли­за­ция изо­бра­же­ния
 $black = $im->colorAllocate(0, 0, 0); #--Соз­да­ем цве­то­вую па­лит­ру
 $red = $im->colorAllocate(255, 0, 0);
 $blue = $im->colorAllocate(0,0,255);
 $yellow = $im->colorAllocate(255,250,0);
 $bg = $im->colorAllocate(240,240,240);
 $gray = $im->colorAllocate(128,128,128);
 $im->fill(0,0,$bg); #--Де­ла­ем за­лив­ку фо­на
 $im->rectangle(0,0,424,249,$black); #--Ри­су­ем гра­ни­цы изо­бра­же­ния
 $poly = new GD::Polygon; #--Ини­циа­ли­за­ция по­ли­го­на
 $poly->addPt(5,50);
 $poly->addPt(25,25);
 $poly->addPt(100,50);
 $poly->addPt(70,95);
 $poly->addPt(30,100);
 $im->filledPolygon($poly,$blue); #--Соз­да­ние по­ли­го­на
 $poly->offset(100,100); #--Сме­ще­ние по­ли­го­на
 $im->polygon($poly,$red); #--Ри­су­ем толь­ко кон­тур
 $poly->map($poly->bounds,190,10,390,150); #--Из­ме­не­ние мас­шта­ба по­ли­го­на в 2 раза
 $im->filledPolygon($poly,$yellow);
 $im->arc(180,50,95,75,0,360,$blue); #--Ри­су­ем эл­лип­сы и ду­ги
 $im->arc(280,190,90,50,290,180,$blue);
 $im->arc(380,190,50,90,0,360,$blue);
 $im->fill(380,190,$red);
 $im->filledRectangle(10, 130, 50, 240, $gray); #--Ри­су­ем че­ты­рех­уголь­ник
 $im->rectangle(10,130,50,240,$black);
 $string=”LINUX FORMAT”;
 $im->string(gdMediumBoldFont,260,25,$string,$blue); #--За­да­ем ста­ти­че­ские шриф­ты
 $im->string(gdSmallFont,170,235,”Copyright 2010”,$black);
 print “Content-Type: image/gif\n\n;
 binmode STDOUT;
 print $im->gif(); #--Пре­об­ра­зо­ва­ние дан­ных в фор­мат GIF и вы­вод

По­ка­зан­ный вы­ше код по­зво­ля­ет web-про­грам­ми­сту по­зна­ко­мить­ся на прак­ти­ке с основ­ны­ми коман­да­ми для ри­со­вания и мо­жет по­слу­жить осно­вой для са­мо­стоя­тель­но­го соз­дания бо­лее серь­ез­ных про­грамм. По­лу­чен­ный ре­зуль­тат мож­но по­смот­реть на рис. 1.

Основ­ные ме­то­ды

В ие­рар­хии ин­тер­фей­сов GD наи­боль­шее рас­про­странение по­лу­чи­ли два ти­па вер­сий для ра­бо­ты с растро­вой гра­фи­кой. Пер­вый тип под­дер­жи­ва­ет манипу­ли­ро­вание и пре­об­ра­зо­вание изо­бра­жений в фор­ма­те GIF. Вто­рой тип ин­тер­фей­сов GD по­зво­ля­ет ра­бо­тать с та­ки­ми по­пу­ляр­ны­ми гра­фи­че­ски­ми фор­ма­та­ми, как PNG и JPEG.

Для за­кре­п­ления по­лу­чен­ных вы­ше прак­ти­че­ских на­вы­ков рас­смот­рим несколь­ко «тео­ре­ти­че­ских» мо­мен­тов инициа­ли­за­ции основ­ных ме­то­дов GD. Вы­зов ме­то­да GD::Image::new(Wx,Hy) воз­вра­ща­ет но­вое пустое изо­бра­жение, на­при­мер:

 $myImage = new GD::Image(100,100) || die;

Ме­тод соз­да­ет пустой бланк изо­бра­жения раз­ме­ром 100 × 100 то­чек. Ес­ли раз­мер опу­щен, он бу­дет со­став­лять 64 × 64 то­чек. Ме­тод GD::Image::newFromGif(FILE) соз­да­ет изо­бра­жение на осно­ве дан­ных фай­ла в фор­ма­те GIF, пред­ва­ри­тель­но про­чи­тан­но­го с диска. Па­ра­метр FILE пред­став­ля­ет со­бой ука­за­тель фай­ла (де­ск­рип­тор). Де­ск­рип­тор фай­ла ука­зы­ва­ет­ся как один из па­ра­мет­ров функ­ции open(). Ес­ли от­кры­тие фай­ла бы­ло успеш­ным, то вы­зов воз­вра­ща­ет инициа­ли­зи­ро­ван­ное изо­бра­жение, ко­то­рое за­тем мо­жет быть под­верг­ну­то раз­лич­ным манипу­ля­ци­ям. На­при­мер:

 open (MyGIF,”images/ballon.gif”) || die;
 $myImage = newFromGif GD::Image(MyGIF) || die;
 close MyGIF;

MyGIF здесь – ука­за­тель фай­ла. Вы­зов ме­то­да GD::Image::gif воз­вра­ща­ет ви­део­дан­ные изо­бра­же­ния в фор­ма­те GIF. За­тем их мож­но вы­вес­ти в брау­зер и/или за­пи­сать в файл. На­при­мер:

 open (MyGIF,>images/ballon.gif”);
 binmode(MyGIF);
 print MyGIF $im->gif;
 close (MyGIF);
 print “Content-Type: image/gif\n\n;
 binmode STDOUT;
 print $im->gif;

Ме­тод GD::Image::colorAllocate(R,G,B) пред­на­зна­чен для за­дания и управ­ления цве­том с по­мо­щью RGB-спе­ци­фи­ка­ции – цве­то­вых ком­понент R (крас­ный), G (зе­ле­ный) и B (синий), и в ре­зуль­та­те воз­вра­ща­ет ин­декс цве­то­вой таб­ли­цы. При­мер за­дания жел­то­го цве­та:

 $yellow = $myImage->colorAllocate(255,255,0);

По­лу­чен­ные ин­дек­сы впо­след­ствии мож­но ис­поль­зо­вать для за­дания об­ще­го фо­на изо­бра­жения или для за­лив­ки фи­гур оп­ре­де­лен­ным цве­том. Ме­тод GD::Image::getPixel(x,y) воз­вра­ща­ет индекс цве­то­вой таб­ли­цы под оп­ре­де­лен­ной точ­кой изо­бра­жения с ко­ор­ди­на­та­ми (x,y). Вы­зов это­го ме­то­да мо­жет быть ском­биниро­ван с функ­ци­ей rgb(), ес­ли вам по­тре­бу­ет­ся восста­но­вить спи­сок RGB-ком­понент под вы­бран­ной точ­кой. На­при­мер:

 $index = $myImage->getPixel(20,100);
 ($r,$g,$b) = $myImage->rgb($index);

Ме­тод GD::Image::transparent(colorIndex) от­ме­ча­ет ин­декс colorIndex как про­зрач­ный. Уча­ст­ки изо­бра­жения, на­ри­со­ван­ные этим цве­том, бу­дут неви­ди­мы. Ме­тод при­ме­ня­ет­ся для соз­дания про­зрач­ных фо­нов изо­бра­жений в Web. Про­зрач­ным в изо­бра­жении мо­жет быть толь­ко один цвет. Ниже, на­при­мер, им бу­дет бе­лый:

 open(myGIF,”transptest.gif”);
 $im = newFromGif GD::Image(myGIF);
 $white = $im->colorClosest(255,255,255); 
 $im->transparent($white);
 print $im->gif;
 close myGIF;

Коман­ды ри­со­вания

Эти коман­ды хо­тя и не занима­ют в ие­рар­хии ме­то­дов GD осо­бо­го по­ло­жения, но вы­де­ля­ют­ся сво­ей вы­ра­жен­ной функ­цио­наль­но­стью. Ин­туи­тив­ная про­сто­та команд (ме­то­дов) по­зво­лит вам бы­ст­ро на­ри­со­вать це­лый ряд при­ми­ти­вов или за­про­грам­ми­ро­вать про­из­воль­ный ри­су­нок. Рас­смот­рим ряд наи­бо­лее упот­реб­ляе­мых ме­то­дов.

Ме­тод GD::Image::setPixel(x,y,color)' соз­да­ет точ­ку с ко­ор­ди­на­та­ми (x,y) с оп­ре­де­лен­ным цве­то­вым ин­дек­сом color. Он ниче­го не воз­вра­ща­ет. Систе­ма ко­ор­ди­нат на­чи­на­ет­ся в верхнем ле­вом уг­лу и за­кан­чи­ва­ет­ся в нижнем пра­вом. Нетруд­но пред­ста­вить, что растро­вый пе­ре­бор ко­ор­ди­нат при на­ли­чии функ­цио­наль­ной за­ви­си­мо­сти цве­то­во­го ин­дек­са color от ко­ор­ди­нат (x,y) мо­жет ис­поль­зо­вать­ся для син­те­за изо­бра­жений. Реа­ли­зу­ем при­мер ко­да для фор­ми­ро­вания дву­мер­но­го рас­пре­де­ления функ­ции w=sin(x,y):

Рис. 2. Рис. 2. При­мер син­те­за изо­бра­же­ния.

 $im = new GD::Image($X,$Y);
 $arg=$period*4*$pi*$pi;
 for($j=0;$j<$Y; $j++){
  $y = ($j-$Y/2)/$Y;
  $phy = $y*$y;
 for($i=0;$i<$X; $i++){
  $x = ($i-$X/2)/$X;
  $phx = $x*$x;
  $w = int($a0 + $amp*sin($arg*($pi - $phx - $phy)));
  $gray = $im->colorResolve($w,$w,$w);
 $im->setPixel($i,$j,$gray);
 }}

Ме­тод colorResolve(r,g,b) воз­вра­ща­ет ин­декс цве­та, ко­то­рый точ­но со­от­вет­ству­ет ука­зан­ным крас­ным, зе­ле­ным и си­ним ком­понен­там. Ес­ли та­кой цвет не на­хо­дит­ся в цвет­ной таб­ли­це, то ме­тод до­бав­ля­ет цвет в таб­ли­цу и воз­вра­ща­ет его ин­декс. На рис. 2 пред­став­лен ре­зуль­тат син­те­за изо­бра­жения, соз­дан­но­го в со­от­вет­ствии свы­ше при­ве­ден­ным ко­дом.

Ме­тод GD::Image::rectangle(x1,y1,x2,y2,color) ри­су­ет че­ты­рех­угольник, сто­ро­ны ко­то­ро­го име­ют оп­ре­де­лен­ный цвет color. Ко­ор­ди­на­ты (x1,y1) и (x2,y2) яв­ля­ют­ся верхним ле­вым и пра­вым нижним уг­ла­ми, со­от­вет­ствен­но. При­мер ри­со­вания квад­ра­та раз­ме­ром 90 × 90 то­чек:

 $myImage->rectangle(10,10,100,100,$blue);

Ме­тод GD::Image::polygon(polygon,color) ри­су­ет мно­го­уголь­ник с за­дан­ным цве­том color, при этом чис­ло вер­шин не долж­но быть ме­нее трех. Ес­ли по­след­няя вер­ши­на по­ли­го­на не соз­да­на, ме­тод бу­дет за­крыт. При­мер ри­со­ва­ния тре­уголь­ни­ка:

 $poly = new GD::Polygon;
 $poly->addPt(50,0);
 $poly->addPt(99,99);
 $poly->addPt(0,99);
 $myImage->polygon($poly,$blue);

Ме­тод GD::Image::line(x1,y1,x2,y2,color) ри­су­ет линию с оп­ре­де­лен­ным цве­том color от точ­ки с ко­ор­ди­на­та­ми (x1,y1) до точ­ки с ко­ор­ди­на­та­ми (x2,y2). При­мер ри­со­вания диа­го­наль­ной синей линии от точ­ки с ко­ор­ди­на­та­ми (7,7) до точ­ки с ко­ор­ди­на­та­ми (154,154):

 $myImage->line(7,7,154,154,$blue);

Ме­тод ри­со­вания line() очень часто при­ме­ня­ет­ся для по­строения гра­фи­ков функ­ции од­ной пе­ре­мен­ной. Фраг­мент ко­да скрип­та, реа­ли­зую­щий основ­ной цикл фор­ми­ро­вания линии гра­фи­ка, а так­же оси абс­цисс и зна­чений пе­ре­мен­ной по оси абс­цисс, пред­став­лен ниже:

Рис. 3. Рис. 3. При­мер по­строе­ния гра­фи­ка функ­ции од­ной пе­ре­мен­ной.

 $f=0;
 for($i=0;$i<$N-1;$i++){
 $im->line($x,$y[$i],$x+$dx,$y[$i+1],$blue);
 $im->line($x,$yh,$x+$dx,$yh,$black);
 $im->string(gdTinyFont, $x, $yh+2, $f, $blue);
 $f +=5;
 $x=$x+$dx;
 }

При­мер ри­со­вания гра­фи­ка функ­ции од­ной пе­ре­мен­ной по­ка­зан на рис. 3.

С по­мо­щью ме­то­да GD::Image::arc(cx,cy,Wx,Hy,start,end,color) мож­но ри­со­вать ду­ги и эл­лип­сы. Ко­ор­ди­на­ты (cx,cy) яв­ля­ют­ся цен­тром эл­лип­са (ду­ги), а па­ра­мет­ры (Wx,Hy) яв­ля­ют­ся ши­ри­ной и вы­со­той эл­лип­са, со­от­вет­ствен­но. Часть эл­лип­са по­кры­ва­ет­ся ду­гой, дли­на ко­то­рой управ­ля­ет­ся па­ра­мет­ра­ми start и end. Эти па­ра­мет­ры за­да­ют­ся в уг­ло­вой ме­ре от 0 до 360 гра­ду­сов. При­мер ри­со­вания пол­но­го эл­лип­са:

 $myImage->arc(100,100,50,35,0,360,$blue);

Ме­тод GD::Image::fill(x,y,color) слу­жит для за­лив­ки об­ластей изо­бра­жения с за­дан­ным цве­том color. Цвет бу­дет рас­про­стра­нять­ся по изо­бра­жению, на­чи­ная от точ­ки (x,y) до границ объ­ек­та, на ко­то­рых по­яв­ля­ет­ся раз­но­ст­ный цвет. При­мер за­лив­ки синим цве­том, на­чи­ная с точ­ки с ко­ор­ди­на­та­ми x=50 и y=40:

 $myImage->rectangle(10,10,100,100,$black);
 $myImage->fill(50,40,$blue);

Ко­пи­ро­вание

Коман­ды ко­пи­ро­вания изо­бра­жений вы­де­ля­ют­ся сво­ей функ­цио­наль­но­стью и важ­ны с точ­ки зрения соз­дания эф­фек­тив­но­го ко­да при ри­со­вании мно­же­ства по­вто­ряю­щих­ся уча­ст­ков изо­бра­жения. При напи­сании ко­да про­грам­мы этот ме­тод по­зво­лит за­помнить неко­то­рую об­ласть изо­бра­жения ана­ло­гич­но то­му, как это де­ла­ет­ся с обыч­ны­ми мас­си­ва­ми дан­ных в Perl.

Ме­тод GD::Image::copy(sourceImage,dstX,dstY,srcX,srcY,Wx,Hy) пред­на­зна­чен для ко­пи­ро­вания пря­мо­уголь­ных об­ластей от од­но­го изо­бра­жения к дру­го­му. Изо­бра­жение-источник за­да­ет­ся с по­мо­щью па­ра­мет­ра sourceImage. Па­ра­мет­ры (srcX,srcY) за­да­ют верхний ле­вый угол пря­мо­угольника в изо­бра­жении-источнике, а (Wx, Hy) ука­зы­ва­ют ши­ри­ну и вы­со­ту об­ласти ко­пи­ро­вания. Па­ра­мет­ры (dstX,dstY) управ­ля­ют ко­ор­ди­на­та­ми точ­ки, в ко­то­рой бу­дет на­чи­нать­ся на­ло­жение ко­пии на изо­бра­жение-по­лу­ча­тель. Вы­зов ме­то­да воз­вра­ща­ет дан­ные изо­бра­жения-по­лу­чате­ля. При­мер ко­пи­ро­вания об­ласти $srcImage раз­ме­ром 25 × 25 то­чек в об­ласть $myImage с на­ча­лом в точ­ке (10,10) по­ка­зан ниже:

 $myImage = new GD::Image(100,100);
 $srcImage = new GD::Image(50,50);
 $myImage->copy($srcImage,10,10,0,0,25,25);

С изо­бра­зи­тель­ной точ­ки зрения, бо­лее ин­те­рес­ным ме­то­дом яв­ля­ет­ся ме­тод GD::Image::copyMerge(sourceImage,dstX,dstY,srcX,srcY,Wx,Hy,opaque), ко­то­рый от­ли­ча­ет­ся от пре­ды­ду­ще­го все­го лишь одним па­ра­мет­ром opaque. Он мо­жет при­го­дить­ся для соз­дания кол­ла­жей. С по­мо­щью па­ра­мет­ра opaque в диа­па­зоне зна­чений от 0 до 100 за­да­ет­ся сте­пень про­зрач­но­сти од­но­го изо­бра­жения от­но­си­тель­но дру­го­го, на­при­мер:

Рис. 4. Рис. 4. При­мер слия­ния двух изо­бра­же­ний с эф­фек­том про­зрач­но­сти.

 $image1->copyMerge($image2,$left,$top,0,0,$wx,$hy, 60);

На рис. 4 по­ка­зан при­мер слияния с эф­фек­том про­зрач­но­сти двух изо­бра­жений од­но­го раз­ме­ра. При этом про­зрач­ность вто­ро­го изо­бра­жения от­но­си­тель­но пер­во­го со­став­ля­ет 60 %.

Вы­во­дим текст

Ин­те­рес web-про­грам­ми­стов к ри­со­ванию тек­ста свя­зан со мно­же­ством за­дач, возникаю­щих при соз­дании гра­фи­че­ских эле­мен­тов web-страниц: от слу­чай­но­го на­бо­ра сим­во­лов в за­да­че ав­то­ри­за­ции поль­зо­ва­те­ля (соз­дание так на­зы­вае­мой Captcha), до ри­со­вания во­дя­ных зна­ков в изо­бра­жениях.

Ин­тер­фейс GD под­дер­жи­ва­ет минималь­ный на­бор ста­ти­че­ских шриф­тов и по­зво­ля­ет ри­со­вать сим­во­лы и стро­ки тек­ста в гра­фи­че­ском ви­де. Вы­вод мо­жет вы­пол­нять­ся как в го­ри­зон­таль­ном на­прав­лении, так и в вер­тикаль­ном. Доступ­ны­ми для ри­со­вания шриф­та­ми яв­ля­ют­ся сле­дую­щие: TinyFont, SmallFont, Medium­BoldFont, LargeFont и GiantFont. Ка­ж­дый из этих шриф­тов мо­жет быть им­пор­ти­ро­ван как гло­баль­ная кон­стан­та или как па­кет объ­ек­тов клас­са GD::Font, на­при­мер: GD::Font::gdTinyFont.

Непо­сред­ствен­но для ри­со­вания при­ме­ня­ет­ся два основ­ных ме­то­да: string() и stringUp(). Ме­тод string(font,x,y,string,color) ри­су­ет стро­ку тек­ста, на­чи­ная с по­зи­ции (x,y), в за­дан­ном цве­те и вы­бран­ном шриф­те. Ме­тод stringUp(font,x,y,string,color) ри­су­ет текст с по­во­ро­том на 90 гра­ду­сов в на­прав­лении, про­ти­во­по­лож­ном вра­щению ча­со­вой стрел­ки.

Рас­смот­рен­ные вы­ше шриф­ты име­ют весь­ма ог­раничен­ный диа­па­зон раз­ме­ров, и при этом толь­ко средний шрифт по­зво­ля­ет вы­де­лять сим­во­лы как жир­ные. Дру­гой су­ще­ствен­ный недоста­ток ста­ти­че­ских шриф­тов – это ог­раничение по лока­ли­за­ции исклю­чи­тель­но ла­тиницей.

Ис­поль­зо­вание ди­на­ми­че­ских шриф­тов TrueType обес­пе­чи­ва­ет при ри­со­вании тек­ста прак­ти­че­ски неог­раничен­ные воз­мож­но­сти, и пре­ж­де все­го, лока­ли­за­цию под лю­бой тип ко­ди­ров­ки, при­ме­няе­мый в web-про­грам­ми­ро­вании. Ме­тод для вы­зо­ва шриф­тов име­ет вид GD::Image->stringTTF(). Раз­но­об­ра­зие же су­ще­ствую­щих шриф­тов снима­ет ог­раничения на их доступ­ность. Один из ва­ри­ан­тов вы­зо­ва ме­то­да stringTTF() име­ет вид:

Рис. 5. Рис. 5. При­мер ри­со­ва­ния тек­ста ди­на­ми­че­ски­ми шриф­та­ми.

 $image->stringTTF($fgcolor,$fontname,$ptsize,$angle,$x,$y,$str),

где ар­гу­мен­ты коман­ды – это:

  • ин­декс цве­та fgcolor для ри­со­вания стро­ки тек­ста,
  • путь fontname к вы­бран­но­му фай­лу шриф­та (.ttf),
  • же­лае­мый раз­мер ptsize шриф­та,
  • угол по­во­ро­та angle в ра­диа­нах,
  • де­кар­то­вы ко­ор­ди­на­ты x,y на­ча­ла ри­со­вания,
  • стро­ка тек­ста str.

На рис. 5 по­ка­зан ре­зуль­тат ри­со­вания стро­ки тек­ста несколь­ки­ми ки­рил­ли­че­ски­ми шриф­та­ми: buaril.ttf, bukursv.ttf, buroman.ttf, butimit.ttf, pushkin.ttf, butimes.ttf.

Фор­ма­ты PNG и JPEG

Как бы­ло от­ме­че­но вы­ше, вто­рой тип ин­тер­фей­сов GD пре­достав­ля­ет воз­мож­ность ис­поль­зо­вать гра­фи­че­ские фор­ма­ты PNG и JPEG. Для ра­бо­ты с гра­фи­че­ским фор­ма­том PNG при­ме­ня­ет­ся ме­тод GD::Image->newFromPng($file), ко­то­рый с по­мо­щью де­ск­рип­то­ра фай­ла мо­жет соз­да­вать изо­бра­жения в этом фор­ма­те. Ес­ли от­кры­тие фай­ла бы­ло успеш­ным, то вы­зов воз­вра­ща­ет инициа­ли­зи­ро­ван­ное изо­бра­жение, на­при­мер:

 open (myPNG,”test.png”) || die;
 $myImage = newFromPng GD::Image(\*myPNG) || die;
 close myPNG;
 print “Content-type: image/png\n\n;
 binmode STDOUT;
 print $im->png();

Су­ще­ст­ву­ет дру­гой ва­ри­ант вы­зо­ва с не­по­сред­ст­вен­ным ука­за­ни­ем фай­ла изо­бра­же­ния:

 $myImage = newFromPng GD::Image('test.png')

Для ра­бо­ты с фор­ма­том JPEG при­ме­ня­ет­ся ме­тод GD::Image->newFromJpeg($file). Этот ме­тод бу­дет соз­да­вать изо­бра­жение в фор­ма­те JPEG по­сле чтения фай­ла с диска в том же фор­ма­те:

 $quality=75;
 $image = GD::Image->newFromJpeg($file);
 print “Content-type: image/jpeg\n\n;
 binmode STDOUT;
 print $image->jpeg($quality);

От­ли­чи­тель­ная осо­бен­но­сть ме­то­да jpeg() – на­ли­чие па­ра­мет­ра ка­че­ства $quality, за­дава­емого как це­лое в диа­па­зоне зна­чений от 0 до 100. Чем боль­ше его зна­чение, тем выше ка­че­ство изо­бра­жения, и, есте­ствен­но, боль­ше раз­мер фай­ла на диске. Ес­ли он не за­дан, по умол­чанию бу­дет вы­бра­но сред­нее ка­че­ст­во.

Персональные инструменты
купить
подписаться
Яндекс.Метрика