Autor: Tomasz Jędrzejewski
Data publikacji: 24.08.2004, 18:31 | Ostatnia modyfikacja: 05.11.2006, 21:42
Artykuł opisuje proces tworzenia prostej galerii zdjęć w PHP
Zadziwiająco wielu ludzi ma problemy z tworzeniem galerii zdjęć w PHP. Postanowiłem wyjść im naprzeciw i dostarczyć ten oto artykuł. Odpowie on na pytania:
Zapraszam do lektury.
Nasza galeria oparta bÄ™dzie o bazÄ™ danych MySQL. Przechowywać bÄ™dziemy w niej dane o aktualnie trzymanych w galerii obrazkach. CaÅ‚y skrypt zmieÅ›cimy w trzech plikach. Pierwszy z nich, gallery.php, posÅ‚uży nam do prezentowania galerii internautom. convert.php bÄ™dzie produkować miniaturki, a layout.php przechowa kod HTML. Po tym krótkim wstÄ™pie... bierzemy siÄ™ do pracy :).
Tradycyjnie zaczniemy od bazy danych. Oto źródÅ‚a tabeli:
CREATE TABLE `galeria` ( `id` int(8) NOT NULL AUTO_INCREMENT, `zdjecie` varchar(32) NOT NULL DEFAULT '', `opis` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) TYPE=MyISAM;
Pierwsze pole to ID elementu, drugie - nazwa pliku ze zdjÄ™ciem, a trzecie jest jego opisem. WiÄ™cej pól na razie nam nie potrzeba. DodadzÄ… je sobie już sami czytelnicy w zależnoÅ›ci od potrzeb.
Obrazki nie sÄ… przechowywane w bazie, gdyż jest to metoda wysoce nieefektywna. MusielibyÅ›my siÄ™ bawić polami binarnymi i samodzielnie wyciÄ…gać dane z bazy, a to odbiÅ‚oby siÄ™ na szybkoÅ›ci dziaÅ‚ania skryptu. StÄ…d też wybraÅ‚em najprostszy sposób - pliki przechowywane zwyczajnie na dysku twardym.
Plik layout.php zawiera sam kod galerii, więc nie będziemy poświęcać mu zbyt dużo uwagi:
<?php function lay_header($title){ echo <<<XXX <html> <head> <title>{$title}</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2"/> </head> <body> XXX; } // end lay_header(); function lay_footer(){ echo <<<XXX <p align="center">(c) Zyx, Webcity.pl</p> </body> </html> XXX; } // end lay_footer(); function lay_list_begin(){ echo <<<XXX <table border="0"> <tr> <td>Miniaturka</td> <td>Opis</td> </tr> XXX; } // end lay_list_begin(); function lay_list_element($id, $name, $desc, $dir){ echo <<<XXX <tr> <td><a href="gallery.php?cmd=show&id={$id}"><img src="{$dir}{$name}"/></a></td> <td>{$desc}</td> </tr> XXX; } // end lay_list_begin(); function lay_list_end(){ echo <<<XXX </table> XXX; } // end lay_list_end(); function lay_photo($prev, $next, $name, $desc, $dir){ echo <<<XXX <table border="0"> <tr> <td align="left">{$prev}</td> <td align="right">{$next}</td> </tr> <tr> <td colspan="2"><img src="{$dir}{$name}"/></td> </tr> <tr> <td colspan="2">{$desc}</td> </tr> </table> XXX; } // end lay_photo(); ?>
Skupmy siÄ™ teraz na kodzie samego gallery.php. Na poczÄ…tek definiujemy dwie staÅ‚e zawierajÄ…ce Å›cieżki do peÅ‚nowymiarowych obrazów oraz ich miniaturek. Ponadto zaÅ‚adujemy tutaj poprzednio stworzony plik oraz połączymy siÄ™ z bazÄ… danych.
<?php define('BIG_DIR', './img/big/'); define('SMALL_DIR', './img/small/'); require('layout.php'); mysql_connect('localhost', 'root', ''); mysql_select_db('moja_kurde_baza');
Teraz zabierzmy się za obsługę akcji. Będą ich dwie - "show", pokazująca pojedynczy obrazek, oraz domyślna wyświetlająca listę miniaturek.
switch($_GET['cmd']){ case 'show': $r = mysql_query('SELECT zdjecie, opis FROM galeria WHERE id=\''.mysql_real_escape_string($_GET['id']).'\''); if(!($row = mysql_fetch_row($r))){ die('Brak podanego zdjęcia!'); } $r = mysql_query('SELECT MAX(id) FROM galeria WHERE id < \''.mysql_real_escape_string($_GET['id']).'\''); $prev = mysql_fetch_row($r); if($prev[0] != ''){ $prev = '<a href="gallery.php?cmd=show&id='.$prev[0].'">Poprzedni</a>'; }else{ $prev = ''; } $r = mysql_query('SELECT MIN(id) FROM galeria WHERE id > \''.mysql_real_escape_string($_GET['id']).'\''); $next = mysql_fetch_row($r); if($next[0] != ''){ $next = '<a href="gallery.php?cmd=show&id='.$next[0].'">Następny</a>'; }else{ $next = ''; } lay_header('Podgląd zdjęcia'); lay_photo($prev, $next, $row[0], $row[1], BIG_DIR); break;
Najpierw pobieramy informacje o samym zdjÄ™ciu. NastÄ™pnie skrypt zabiera siÄ™ za generowanie linków "Poprzedni" oraz "NastÄ™pny". Wbrew pozorom, uzyskanie ID poprzedniego i nastÄ™pnego rekordu jest bardzo proste. Pokażę to na przykÅ‚adzie pierwszego linka ("Poprzedni"). KlauzulÄ… WHERE zawężam obszar poszukiwaÅ„ do rekordów majÄ…cych ID mniejsze od ID aktualnego zdjÄ™cia. Na tak ograniczonym zbiorze wywoÅ‚ujÄ™ funkcjÄ™ MAX(id), która zwróci mi najwiÄ™kszy znajdujÄ…cy siÄ™ w nim ID. Jako, że identyfikatory sÄ… zawsze posortowane, oznacza to, że dostanÄ™ ID poprzedniego elementu. Podobnie jest z linkiem "NastÄ™pny", tyle że robimy na odwrót: dajemy elementy wiÄ™ksze i funkcjÄ™ MIN(id).
WyÅ›wietlanie listy miniaturek nie wymaga chyba szczegóÅ‚owego omawiania.
default: lay_header('Galeria'); $r = mysql_query('SELECT id, zdjecie, opis FROM galeria ORDER BY id'); lay_list_begin(); while($row = mysql_fetch_row($r)){ lay_list_element($row[0], $row[1], $row[2], SMALL_DIR); } lay_list_end(); } lay_footer(); mysql_close(); ?>
Do produkcji miniaturek użyjemy biblioteki GD w wersji 2. Pozwala ona na manipulację obrazami. Niestety nasz konwerter nie będzie obsługiwać formatu GIF w powodu braku obsługi takowego w ww. bibliotece (problemy patentowe).
Zaczniemy od detekcji formatu, w jakim zapisany jest oryginalny plik. Potrzebujemy tego do załadowania pliku do pamięci komputera:
<?php if(strpos($_GET['nazwa'], '.jpg') !== FALSE){ $img = imagecreatefromjpeg('./img/big/'.$_GET['nazwa']); $format = 0; }elseif(strpos($_GET['nazwa'],'.png') !== FALSE){ $img = imagecreatefrompng('./img/big/'.$_GET['nazwa']); $format = 1; }else{ die('Format nieobsługiwany'); }
Kolejnym krokiem bÄ™dzie zestaw obliczeÅ„ matematycznych, dziÄ™ki którym w miniaturce zostanie zachowany odpowiedni stosunek dÅ‚ugoÅ›ci do szerokoÅ›ci obrazka.
// Wymiarowanie rysunku $x = imagesx($img); $y = imagesy($img); if($x > $y){ $nx = 200; $ny = 200 * ($y / $x); }elseif($x < $y){ $nx = 200 * ($x / $y); $ny = 200; }else{ $nx = 200; $ny = 200; }
Za podstawowy rozmiar pliku przyjÄ…Å‚em 200 pikseli. Jest on przypisywany zawsze dÅ‚uższemu bokowi. Do krótszego natomiast przypisujemy rozmiar podstawowy pomnożony przez ww. stosunek obliczany z wzoru: krótszy bok / dÅ‚uższy bok. Uzyskane dane podstawiamy do funkcji imagecopyresampled(), która wprowadzi nam zmiany do zdjÄ™cia.
$new_img = imagecreatetruecolor($nx, $ny); imagecopyresampled($new_img, $img, 0, 0, 0, 0, $nx, $ny, $x, $y);
Funkcja ta nie operuje na tym samym obrazie - przeskalowane zdjÄ™cie musi zostać zapisane w nowym miejscu, które stworzyliÅ›my wczeÅ›niej funkcjÄ… imagecreatetruecolor(). UtworzonÄ… miniaturkÄ™ zapisujemy na twardy dysk:
if($format == 0){ imagejpeg($new_img, './img/small/'.$_GET['nazwa'], 9); }else{ imagepng($new_img, './img/small/'.$_GET['nazwa']); } ?>
Skrypt wywołujemy następująco: convert.php?nazwa=nazwa_pliku.
Autor: Tomasz "Zyx" Jędrzejewski, www.zyxist.com
Waszym zdaniem:
Nikt jeszcze nie dodał swojego komentarza. Możesz być pierwszy!