Galeria w PHP

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();
 
?>
Produkcja miniaturek

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.

Do góry

Zakończenie
Nasza galeria jest już gotowa. Pozostaje już tylko dodanie rekordów do bazy, utworzenie miniaturek i podziwianie efektów. Niemniej jednak, nie jest to koniec pracy. Brakuje jeszcze choćby panelu administracyjnego oraz stronicowania miniaturek, co przydaje się szczególnie przy dużych galeriach. Ale to pozostawiam już Twojej inwencji - wszak ćwiczenie czyni mistrza.

Autor: Tomasz "Zyx" Jędrzejewski, www.zyxist.com

Do góry

Waszym zdaniem:

Nikt jeszcze nie dodał swojego komentarza. Możesz być pierwszy!


Twoim zdaniem:

Reklama

banner

Partnerzy

CityDesign.pl
phpSolutions