|
ÀÁÐÀÊÀÄÀÁÐÀ (Òîæå ñàìîå íî â ÷èòàåìîì âèäå)
Stat'a opisivaet metodiku slojnogo formatirovania izobrajeniy na PHP pod nujniy format nezavisimo ot ix na4al'nix razmerov i orientacii, no vsegda vida¸t izobrajenia strogo opredel¸nnogo razmera. V skripte ispol'zuutsa funkcii obrabotki izobrajeniy biblioteki GD. Skript budet polezen dla novostnix saytov i fotogalerey. Sut' problemiRabotaa nad novostnim saytom, a stolknulsa s problemoy xranenia kartinok k stat'am v dvux formatax – melkiy (90 na 90 dla zagolovo4nix blokov) i krupniy (218 na skol'ko est'). Novosti xranilis' v baze i dobavlalis' o4en' prosto. S kartinkami vixodilo slojnee. Isxodnie izobrajenia s cifrovoy fotokameri (ili cifrovogo maketa bumajnoy gazeti) zagrujalis' v PhotoShop i obrabativalis' dizaynerom pod nujniy format. Uje sam fakt ru4noy raboti s grafikoy zastavil zadumat'sa ob avtomatizacii. Krome togo, prixodilos' lokal'no soxranat' dve kartinki, a potom zaka4ivat' ix 4erez formu po otdel'nosti, da 4tob e6¸ i ne pereputat', gde kakaa! Voznikaet izbito4nost', a razmer zanimaemogo mesta stanovilsa vs¸ bol'6e i bol'6e. Pervie ideiS samogo na4ala raboti nad proektom a znal, 4to su6estvuet takaa ve6', kak ImageMagick dla Perl. Zapustit' etot 4udo-modul' mne tak i ne udalos'. Potom a pere6¸l na PHP, i ponal, 4to Perl ne sovsem prisposoblen dla takix ve6ey. Na PHP toje mojno formirovat' kartinki s pomo6'u modula GD. On xot' i popro6e budet, no funkcii mas6tabirovania v n¸m est', 4to i trebovalos'. Postanovka zada4i – napisat' skript, polu4au6iy put' isxodnogo izobrajenia i vivodil bi dannie image/jpeg – kartinku nujnogo formata (sm. opisanie protokola HTTP). Skript mas6tabirovania resize.phpVxodnie parametri: - $f – ima fayla v vide path/file.jpg. Mojno bilo pridumat' bolee za6i6¸nniy sposob adresacii, no sut' algoritma ne menaetsa. Naprimer, predavat' tol'ko nomer stat'i iz bazi, a skript sam bi opredelil mestonaxojdenie kartinki;
- $q – ka4estvo sjatia JPEG;
- $type – format kartinki (v smisle lineynie razmeri) gde v zavisimosti ot zna4enia $type proizvodatsa sleduu6ie deystvia:
- $type = 0 – iz isxodnoy kartinki virezaetsa kvadratnaa seredinka i privoditsa k formatu 90x90 pikseley;
- $type = 1 – isxodnaa kartinka mas6tabiruetsa proporcional'no i privoditsa k 6irine 218 pikseley (opcional'no nanositsa nadpis');
- $type = 2 – isxodnaa kartinka vivoditsa bez izmeneniy.
Posmotrim na4alo skripta: resize.php <?php
// f - ima fayla // type - sposob mas6tabirovania // q - ka4estvo sjatia // src - isxodnoe izobrajenie // dest - rezul'tiruu6ee izobrajenie // w - 6irnia izobrajenia // ratio - koefficient proporcional'nosti // str - tekstovaa stroka
// tip preobrazovania, esli ne ukazani razmeri if ($type == 0) $w = 70; // kvadratnaa 70x70 if ($type == 1) $w = 90; // kvadratnaa 90x90 if ($type == 2) $w = 218; // proporcional'naa 6irinoy 218
// ka4estvo jpeg po umol4aniu if (!isset($q)) $q = 100;
Zdes' kak obi4no proverautsa vxodnie parametri. Vi, kone4no, mojete zadat' bolee j¸stkie uslovia proverki. Smotrim dal'6e. // sozda¸m isxodnoe izobrajenie na osnove // isxodnogo fayla i operedelaem ego razmeri $src = imagecreatefromjpeg($f); $w_src = imagesx($src); $h_src = imagesy($src);
header("Content-type: image/jpeg");
V etoy 4asti programmi mi zagrujaem isxodnoe izobrajenie v peremennuu $src. Funkcii imagesx i imagesy opredelaut razmeri isxodnoy kartinki i zapisivaut ix v sootvetstvuu6ie peremennie. Oni nam ponadobatsa dla vi4islenia koefficienta proporcional'nosti. Zdes' je s pomo6'u funkcii header pereda¸m zagolovok Content-type: image/jpeg v brauzer pol'zovatela. Posle etogo on ojidaet, 4to sleduu6iy potok dannix budet jpeg-faylom. Sleduu6ee uslovie otve4aet za razmer vivodimoy kartinki i neposredstvenno za vivod. Vozmojno, 4to isxodnaa kartinka uje nujnogo razmera. Esli eto ne tak, obrabotaem e¸. Dla etogo postavim sleduu6ee uslovie: // esli razmer isxodnogo izobrajenia // otli4aetsa ot trebuemogo razmera if ($w_src != $w) {
Sleduu6aa 4ast' programmi budet podgonat' kartinku pod 6irinu 218 pikseley (proporcional'noe umen'6enie) dla slu4aa $type=1. // operacii dla polu4enia pramougol'nogo fayla if ($type==2) { // vi4islenie proporciy $ratio = $w_src/$w; $w_dest = round($w_src/$ratio); $h_dest = round($h_src/$ratio);
// sozda¸m pustuu kartinku // vajno imenno truecolor!, ina4e budem imet' 8-bitniy rezul'tat $dest = imagecreatetruecolor($w_dest,$h_dest); $str = "foxweb.net.ru"; imagecopyresized($dest, $src, 0, 0, 0, 0, $w_dest, $h_dest, $w_src, $h_src);
Vna4ale vi4islaem koefficient $ratio, 4tobi srazu vi4islit' razmeri rezul'tiruu6ey kartinki $w_dest i $h_dest. Potom sozda¸m novuu kartinku $dest s takim je razmerami, eto zagotovka dla mas6tabirovannoy kartinki. Samaa slojnaa 4ast' algoritma – funkcia imagecopyresized. V ney a ukazal rezul'tiruu6uu i isxodnuu kartinku, koordinati levogo verxnego ugla dla oboix kartinok (0, 0, 0, 0) i koordinati pravogo nijnego ugla dla oboix kartinok ($w_dest, $h_dest, $w_src, $h_src). Vot oficial'naa spravka na etu funkciu: imagecopyresized - kopiruet i izmenaet razmeri 4asti izobrajenia int imagecopyresized ( resource dst_im, resource src_im, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH) imagecopyresized() kopiruet pramougol'nuu 4ast' odnogo izobrajenia v drugoe izobrajenie. Dst_im - rezul'tiruu6ee izobrajenie, src_im - isxodnoe izobrajenie. Esli isxodnie i koordinati raspolojenia i 6irini i visot otli4autsa, budet vipolneno rastajenie ili sjatie fragmenta izobrajenia. Na4alo koordinat - verxniy leviy ugol. Eta funkcia mojet bit' ispol'zovana, 4tobi kopirovat' oblasti v predelax togo je izobrajenia (esli dst_im i src_im sovpadaut), no esli oblasti perekrivaut rezul'tati bit' nepredskazuemim. Vmesto ne¸ mojno ispol'zovat' imagecopyresampled() - resemplirovanie so sglajivaniem. Kartinka polu4itsa bolee ka4estvennoy. Podrobnee o parametrax funkcii mojno uznat' v dokumentacii na sayte http://php.net/imagecopyresized/ . Sleduu6aa 4ast' koda sover6enno neobazatel'na. Ona pe4ataet proizvol'nuu nadpis' na gotovoy kartinke. Pri4¸m, kontrastnim cvetom: na t¸mnom fone nadpis' budet belaa, na svetlom – 4¸rnaa. Sna4ala opredelim koordinati vivoda teksta (v na6em primere eto vnizu sprava) i tri cveta – $white, $black i $gray s pomo6'u funkcii imagecolorallocate. 4tobi opredelit', kakim cvetom pe4atat' nadpis', sravnim cvet to4ki (funkcia imagecolorat), gde budet nadpis', so «srednim» cvetom $gray. Esli cvet to4ki okajetsa svetlee serogo, to nadpis' budet 4¸rnogo cveta ($color = $black). Esli cvet to4ki okajetsa temnee serogo, to nadpis' budet belogo cveta ($color = $white). Nakonec opredelaem stroku $str i nanosim e¸ funkciey imagestring, ukazav razmer 6rifta, koordinati, stroku i cvet. Pomnite, 4to eta funkcia vivodit tol'ko latinskie simvoli odnim 6riftom. Xota nikto ne zapre6aet vam pol'zovat'sa TrueType 6riftami, blago takie funkcii est'. // opredelaem koordinati vivoda teksta $size = 2; // razmer 6rifta $x_text = $w_dest-imagefontwidth($size)*strlen($str)-3; $y_text = $h_dest-imagefontheight($size)-3;
// opredelaem kakim cvetom na kakom fone vivodit' tekst $white = imagecolorallocate($dest, 255, 255, 255); $black = imagecolorallocate($dest, 0, 0, 0); $gray = imagecolorallocate($dest, 127, 127, 127); if (imagecolorat($dest,$x_text,$y_text)>$gray) $color = $black; if (imagecolorat($dest,$x_text,$y_text)<$gray) $color = $white;
// vivodim tekst imagestring($dest, $size, $x_text-1, $y_text-1, $str,$white-$color); imagestring($dest, $size, $x_text+1, $y_text+1, $str,$white-$color); imagestring($dest, $size, $x_text+1, $y_text-1, $str,$white-$color); imagestring($dest, $size, $x_text-1, $y_text+1, $str,$white-$color);
imagestring($dest, $size, $x_text-1, $y_text, $str,$white-$color); imagestring($dest, $size, $x_text+1, $y_text, $str,$white-$color); imagestring($dest, $size, $x_text, $y_text-1, $str,$white-$color); imagestring($dest, $size, $x_text, $y_text+1, $str,$white-$color);
imagestring($dest, $size, $x_text, $y_text, $str,$color); }
Neskol'ko slojnee vigladit 4ast' koda dla polu4enia kvadratnogo fragmenta. // operacii dla polu4enia kvadratnogo fayla if (($type==0)||($type==1)) { // sozda¸m pustuu kvadratnuu kartinku // vajno imenno truecolor!, ina4e budem imet' 8-bitniy rezul'tat $dest = imagecreatetruecolor($w,$w);
// virezaem kvadratnuu seredinku po x, esli foto gorizontal'noe if ($w_src>$h_src) imagecopyresized($dest, $src, 0, 0, round((max($w_src,$h_src)-min($w_src,$h_src))/2), 0, $w, $w, min($w_src,$h_src), min($w_src,$h_src));
// virezaem kvadratnuu verxu6ku po y, // esli foto vertikal'noe (xota mojno toje seredinku) if ($w_src<$h_src) imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $w, min($w_src,$h_src), min($w_src,$h_src));
// kvadratnaa kartinka mas6tabiruetsa bez virezok if ($w_src==$h_src) imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $w, $w_src, $w_src); }
// vivod kartinki i o4istka pamati imagejpeg($dest,'',$q); imagedestroy($dest); imagedestroy($src); }
Mi ne opredelaem koefficient mas6tabirovania, poskol'ku kartinka budet kvadratnoy zaranee izvestnogo razmera. Po razmeru kartinka mojet bit' tr¸x tipov – gorizontal'naa, vertikal'naa i kvadratnaa. V pervix dvux slu4aax nam prid¸tsa virezat' i mas6tabirovat' kvadratnuu oblast' iz pramougol'noy kartinki. V tret'em – prosto mas6tabirovat'. Nemnogo poasnu konstrukciu: round((max($w_src, $h_src) – min($w_src, $h_src)) / 2). Eto virajenie vi4islaet koordinatu x ili y verxnego levogo ugla kvadratnogo bloka (bez raznici dla gorizontal'noy ili vertikal'noy kartinki). Eto vidno na risunkax. Gorizontal'noe izobrajenie | | | Vertikal'noe izobrajenie | | |
Obi4no v gorizontal'nix kartinkax (lica, peyzaji, ob&ekti) naibolee informativna central'naa 4ast', a v vertikal'nix (4a6e vsego eto stoa6ie ludi) - naibolee vajna verxnaa 4ast'. 4tobi izmenit' virezaemiy fragment vertikal'noy kartinke, stroku: imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $w, min($w_src,$h_src), min($w_src,$h_src));
mojno zamenit' na imagecopyresized($dest, $src, 0, 0, 0, round((max($w_src,$h_src)-min($w_src,$h_src))/2), $w, $w, min($w_src,$h_src), min($w_src,$h_src));
Togda v vertikal'noy kartinke budet brat'sa ne verxnaa 4ast', a srednaa (eto zavisit ot raspolojenia ob&ektov na fotografii). To4no tak je mojno brat' nijnuu 4ast' ili pravuu/levuu 4ast' gorizontal'noy kartinki – poeksperimentiruyte s koordinatami. Osobenno etot metod prigoditsa, esli nujno sozdat' kvadratnie «prev'u6ki» (thumbnails) v odnoy tablice. V konce vivodim kartinku imagejpeg() i o4i6aem pamat' imagedestroy(). Demonstracia mas6tabirovania4tobi vam ne prixodilos' lixorado4no menat' vxodnie peremennie v processe otladki na lokal'nom servere, predlagau demo-strani4ku, kotoraa zagrujaet 4etire kartinki raznix formatov. Testovie isxodnie kartinki doljni xranit'sa v teku6ey direktorii pod imenami image1.jpg i image2.jpg. Zdes' je doljen naxodit'sa fayl resize.php, kotoriy na vivode vida¸t jpeg-izobrajenie. resize.htm <html> <head> <title></title> </head> <body> <h3 align="center">Demonstracionniy primer mas6tabirovania kartinok</h3> <table align="center"> <tr align="center" valign="top"> <td>90*90<br><img src="resize1.php?f=av.jpg&t=1&w=90&s=0" border=0></td> <td>90*90<br><img src="resize.php?f=news114.jpg&type=1" border=0></td> </tr> <tr align="center" valign="top"> <td>218*x<br><img src="resize.php?f=av.jpg&type=2" border=0></td> <td>218*x<br><img src="resize.php?f=news114.jpg&type=2" border=0></td> </tr> </table> </body> </html> Prosmotrov6ik kartinokEtot skript dostato4no prost, on vsego li6' formiruet stranicu, ssilki, osu6estvlaet vsu navigaciu po katalogu kartinok. Vsa rabota po zagruzke kartinok proizvoditsa 4erez resize.php. Ego mojno vzat' za osnovu prostogo veb-al'boma. preview.php <html> <head> <title></title> </head> <body> <?php
// 4itaem spisok jpg-faylov v massiv list $list = array(); if ($dir = opendir('.')) // uspe6noe otkritie teku6ey direktorii { // perebiraem imena faylov, polu4ennie readdir while (false !== ($file = readdir($dir))) { // otbiraem tol'ko .jpg, otsekaem ssilki '.' i '..' if ($file != "." && $file != ".." && preg_match("/.jpg/i", $file)) { $list[] = $file; // pi6em ima fayla v massiv $i++; // s4¸t4ik faylov, nujen dla opredelenia granic massiva } } closedir($dir); // zakrivaem direktoriu }
// peremennie po umol4aniu, polu4ennie 4erez GET if ($f == '') $f = $list[0]; // esli fayl ne ukazan, ber¸m perviy iz spiska if ($num == '') $num = 0; // nomer zapro6ennogo fayla if ($type == '') $type = 1; // tip po umol4aniu "sredniy"
// zagolovo4ek - ima fayla echo "<p>$list[$num]</p>n";
// opredelaem ssilku s kartinki analizirua type // 6¸lkaa po kartinke fayl budet perezagrujat'sa s novim type if ($type == 0) $link = "href="?type=1&num=$num" title="pokazat' 90""; if ($type == 1) $link = "href="?type=2&num=$num" title="pokazat' 218""; if ($type == 2) $link = "href="?type=full&num=$num" title="pokazat' ves'""; if ($type == "full") $link = "href="?type=0&num=$num" title="pokazat' 70""; echo "<a $link><img src="resize.php?f=$list[$num]&type=$type" border=0></a>";
// opredelaem, kraynie li elementi spiska $num1 = $num-1; if ($num1<0) $num1 = $i-1; // esli num vi6el za 0, perevodim ego na 0 $num2 = $num+1; if ($num2>$i-1) $num2 = 0; // esli num vi6el za i, perevodim ego na i-1
// ssilki navigacii echo "<br><a href="?type=$type&num=$num1">pred</a> <a href="?type=$type&num=$num2">sled</a>";
?> </body> </html>
Dumau, 4to skript dostato4no xoro6o kommentirovan, potomu ob&asnu li6' sut'. Vna4ale proisxodit zagruzka im¸n jpg-faylov v teku6em kataloge v massiv $list. Potom zagrujaem kartinku s nujnimi parametrami iz skripta resize.php, pri4¸m na kartinke «visit» ssilka na e¸ uveli4ennuu kopiu (izmenaetsa parametr $type). V konce formiruem ssilki na sleduu6uu i predidu6uu kartinku. Vot i vs¸. V ka4estve testirovania nakidayte v katalog skripta dva desatka fotografiy i vi polu4ite prosten'kuu «smotrelku». Navigaciu, kone4no, mojno uslojnit', no togda skript uje budet «slojnen'kim». Po4emu ne rabotaet GD?A otlajivau skripti v Windows, poetomu ob&asnu re6enie problemi imenno dla etoy OS. Skoree vsego, pri4ina nerabotosposobnosti skripta v otsutstvii modula php_gd.dll (ili bolee noviy php_gd2.dll). Otkroyte direktoriu s interpretatorom PHP, sozdayte direktoriu extensions, esli e¸ net. Naydite vi6eukazanniy modul' – on est' v polnix distributivax PHP. Propi6ite v php. ini (lejit v c: windows) stro4ku extension = php_gd2.dll (a zaodno i extension_dir = "c:phpextensions", esli takoy net). Puti mogut bit' drugimi. Posle etogo vs¸ doljno zarabotat'. Ne «sme6ivayte» moduli php_gd.dll i php_gd2.dll – interpretator budet rugat'sa na dublirovanie funkciy v bibliotekax. Zaklu4enieVot takie interesnie ve6i mojno sdelat' pri pomo6i pari grafi4eskix funkciy – zato kakaa ekonomia na izgotovlenii i xranenii dubliruu6ix kartinok. Ne PhotoShop kone4no, no dla massovogo primenenia eto samoe to. Kartinok na sayte o4en' mnogo, ka4estvenno ix vivodit' neobazatel'no, glavnoe 4tobi bistro i prosto. Skript polu4ilsa ne o4en' universal'niy, no s moey zada4ey on spravlaetsa prekrasno. Sleduet otmetit' tonkuu raznicu mejdu funkciami imagecopyresized i imagecopyresampled. Pervaa prosto izmenaet razmer kartinki bez sglajivania, ona rabotaet bistro, no rezul'tat – bol'6ie iskajenia. Vtoraa funkcia – resemplirovanie, izmenenie razmerov so sglajivaniem. Rabotaet ona namnogo medlennee, no kartinka polu4aetsa 4istoy, kak v professional'nix grafi4eskix paketax. O resemplirovanii mojno po4itat' zdes'. Vibirat' sposob sleduet isxoda iz va6ix potrebnostey – bistree ili ka4estvennee. Vozmojno, vi realizuete drugie idei: zadavat' proizvol'niy razmer x i y, nali4ie ili otsutstvie nadpisi, format vixodnogo fayla, risovanie ramo4ki, vodanix znakov, podpisi na kartinke 6riftami TrueType, vivod kartinki-zaglu6ki v slu4ae o6ibki. Esli kto zametil kakie-to glupie ili sme6nie mesta v programmax, jdu va6ix kommentariev.
Demonstraciu fotogalerei na osnove opisannoy metodiki mojno uvidet' na http://foxweb.net.ru/photo/.
Sayt, dla kotorogo eto vs¸ izna4al'no razrabativalos' – 58region.ru/. Pravda tam ispol'zuetsa uslojn¸nniy variant – resize.php rabotaet s trema tipami faylov, vivodit nadpis' po jelaniu i vivodit kartinku-zaglu6ku v slu4ae otsutstvia isxodnogo fayla.
Proverit' rabotosposobnost' skriptov v onlayne i ska4at' isxodniki obeix versiy mojno tut foxweb.net.ru/test/resize/. Vsegda jdu va6ix kommentariev. Uda4i!
|