Image Resizer
Do tej pory korzystałem z komponentu do obsługi obrazów opisanym w poście http://www.reboo.pl/2008/09/29/imagecomponent-dla-cakephp/. Sprawdzał się on całkiem dobrze, ale ma on swoje wady.
Przede wszystkim często borykałem się z problemem braku pamięci na mniejszych serwerach. Gdy serwer ma do dyspozycji 32MB pamięci, to w sytuacji gdy użytkownik uploaduje zdjęcie o rozmiarach ok. 3k na 2k pikseli, zaczynało brakować zasobów to przetworzenia tego obrazu.
Brakowało mi też obsługi błędów i informacji o powstałych błędach.
Nie lubię też za wiele pisać, więc zależało mi też na minimalizacji operacji potrzebnych do wykonania przeskalowania obrazu.
Napisałem swój obiekt Image i można go pobrać tutaj: http://www.reboo.pl/files/download/image.zip a jako komponent dla CakePHP: http://www.reboo.pl/files/download/image_componnent-v2.zip
Podstawowe funkcje tego obiektu to:
- load($filename) ładuje obraz z podanej ścieżki
- save($filename) zapisuje obraz
- min($width, $height) sprawdza czy obraz nie jest mniejszy od podanych rozmiarów
- rotateRight() obraca obraz w prawo
- rotateLeft() obraca w lewo
- mirror() tworzy lustrzane odbicie
- flip() odbicie w poziomie
- rotate($angle, $color=null, $ignore_transparent=0) obraza obraz o podany kąt, z tłem w wybranym kolorze
- copy($filename, $x=0, $y=0, $width=0, $height=0) kopiuje inny obraz w miejsce o podanych współrzędnych, z możliwością przeskalowania go
- text($size, $angle, $x, $y, $color, $fontfile, $text) rysuje tekst na obrazie
- textFromRight($size, $angle, $x, $y, $color, $fontfile, $text) także ryzuje tekst, ale od prawej od podanych współrzędnych
- zoom($new_width,$new_height) skaluje obraz dopasowując do podanych wymiarów, obcinając wystające części obrazu
- crop($x, $y, $width, $height) obcina obraz
- width($width) skalowanie z dopasowaniem do szerokości
- height($height) skalowanie z dopasowaniem do wysokości
- resize($new_width,$new_height) zwykłe skalowanie
- frame($width, $height, $color=null) zwykłe skalowanie z dopasowaniem do ramki, z tłem w podanym kolorze
- make($from, $to, $params=array()) ekspresowe tworzenie obrazu opisane poniżej
- getErrorMessage() zwraca krótką informację o błędzie
Każda z tych funkcji zwraca wartość typu boolean (false w przypadku niepowodzenia). Wtedy funkcją getErrorMessage() można dowiedzieć się trochę dokładniej co poszło nie tak.
Jeżeli chcemy ekspresowo przeskalować jakiś obraz wystarczy użyć funkcji make podając jako pierwszy parametr ścieżkę obrazu wejściowego, następnie wyjściowego i tablicę parametrów. Może to być: ‘width’, ‘height’, ‘function’.
Wymagane jest użycie przynajmniej ‘width’ lub ‘height’. Wtedy obraz zostanie przeskalowany do jednego z tych wymiarów. Podając oba zostanie wykonana funkcja resize. Jeżeli chcemy wykonać np. zoom, to trzeba podać ten parametr w ‘function’.
Typ zapisywanego obrazu jest rozpoznawany na podstawie wpisanego rozszerzenia w nazwie pliku wyjściowego. Przykłady użycia obiektu Image:
//tworzenie odbicia na szkle
$img->load('beach.jpg');
$img->mirror();
$img->crop(0,0, 100, 60);
$img->copy('mask.png',0,0);
$img->save('beach_reflection.jpg');
//szybkie skalowanie
$img->make('beach.jpg', 'small_beach.jpg', array('width'=>400, 'height'=>400, 'function'=>'zoom'));
Pisałem wcześniej o wykrywaniu możliwości zabraknięcia pamięci. Ładując obraz funkcją load, przed załadowaniem obrazu do pamięci wykonywana jest funkcja canOpen($filename). Sprawdza ona czy jest dość pamięci, jeżeli nie, to próbuje zwiększyć ‘memory_limit’. Jeżeli się nie uda, zwracane jest false i obraz nie jest otwierany. Dzięki temu możemy zapobiec sytuacji, w której przy otwieraniu obrazu zabraknie pamięci. Obliczanie potrzebnej pamięci znalazłem na http://pl2.php.net/manual/pl/function.imagecreatefromjpeg.php i nieco przerobiłem, ponieważ tamta nie zawsze się sprawdzała.
niedziela, 10 Maj 2009
Facebook
GoldenLine
LinkedIn