Wygrzebane z GitHuba (2) : Imagine

Dzisiaj drugi odci­nek Waszego ulubio­nego serialu: Wygrze­bane z GitHuba. Wszyst­kie stacje TV rywa­li­zują o wyłącz­ność na emisję kolej­nego odcinka, padają kwoty sied­mio­cy­frowe wyra­żane w zimba­bwiań­skich dolarach…

Imagine to udana próba ujed­no­li­ce­nia inter­fej­sów różnych biblio­tek graficz­nych w zakre­sie mani­pu­la­cji obra­zami w PHP. Nieważne czy pod maską mamy GD, Image­Ma­gick czy Gmagick. Wszyst­kie opera­cje wyko­namy za pomocą jedno­li­tego inter­fejsu. Doku­men­ta­cja do znale­zie­nia tutaj.

Pomimo tego iż projekt ma dopiero nieco ponad rok, jest przez ten czas wyko­nany kawał dobrej roboty. Projekt ma ładną struk­turę wyra­żoną w name­spa­cach, przez co można śmiało łado­wać tylko potrzebne klasy za pomocą stan­dar­do­wego SplC­las­sLo­adera (do pocią­gnię­cia np. stąd).

O Imagine pisał php|architect, jest również prezen­ta­cja.

Poni­żej zade­mon­struję jak można użyć tego cuda do zmniej­sze­nia zestawu obraz­ków do jedno­li­tych kwadra­tów i wyświe­tlić na ekran w locie. To oczy­wi­ście metoda dla maso­chi­stów CPU, bo normal­nie czło­wiek prze­cież zapi­suje obrazki najpierw na dysk, a dopiero potem wyświe­tla. Efekt, który chcemy uzyskać będzie wyglą­dał tak:

<?php
require_once 'SplClassLoader.php';
 
// rejestrujemy przestrzen nazw Imagine
// i wskazujemy gdzie jej szukac
$classLoader = new SplClassLoader('Imagine', 'lib');
$classLoader->register();
 
// importujemy niezbedne klasy
use Imagine\ImageInterface;
use Imagine\Gd\Imagine;
use Imagine\Image\Box;
use Imagine\Image\Color;
use Imagine\Image\Point;
 
$columns = 2;
$images = 4;
$singleImgSize = 250;
 
// licze calkowita szerokosc tla
$backgroundXSize = (int) $columns * $singleImgSize;
// wysokosc zaokraglam w gore dla nieparzystych
$backgroundYSize = (int) $singleImgSize * ceil($images / $columns);
 
// jezeli mam i chce skorzystac z ImageMakicka
// to po prostu importuje wyzej
// use Imagine\Imagick\Imagine;
$imagine = new Imagine();
 
// tworze pusty obrazek w czarnym kolorze i 0 przezroczystosci
$background = $imagine->create(new Box($backgroundXSize, $backgroundYSize), new Color('000', 0));
 
// tablica z nazwami obrazkow do przeskalowania
// i wyswietlenia
$imagesArray = array('img1.jpg', 'img2.jpg', 'img3.jpg', 'img4.jpg');
 
// punkty startowe wklejania
$x = 0;
$y = 0;
 
foreach ($imagesArray as $img) {
  // otwieram obrazek z dysku,
  // zmniejszam go do kwadratu
  // uzywam trybu OUTBOUND,
  // czyli pilnuję proporcji i wywalam fragmenty dluzszego boku
  $image = $imagine->open('../images/' . $img)
            ->thumbnail(new Box($singleImgSize, $singleImgSize), ImageInterface::THUMBNAIL_OUTBOUND);
 
  // wklejam zmniejszony obrazek do tla
  // podajac lokalizacje lewego gornego rogu wklejania
  $background->paste($image, new Point($x, $y));
 
  // licze pozycje startowa dla nastepnego obrazka  
  $x += $singleImgSize;
  if ($x >= $canvasXSize) {
    $x = 0;
    $y += $singleImgSize;
  }
}
 
// obiekt Image obsluguje metode
// __toString() w postaci danych binarnych PNG
// wystarczy tylko podac naglowki
header('Content-Type: image/png');
// zamiast wyswietlac mozemy uzyc
// $background->save('obrazek.png',array('quality' => 85));
echo $background;

Oprócz typo­wych zadań typu skalo­wa­nie czy konwer­sja na inne formaty, projekt ma aspi­ra­cje na dosyć zaawan­so­wane mani­pu­la­cje obra­zami typu odwra­ca­nie w pozio­mie i pionie, refleksy, wykresy, ujed­no­li­cony inter­fejs ryso­wa­nia obiek­tów, histo­gramy itd.

Obrazki na licen­cji CC-BY poży­czone z Flic­kra. Właści­ciele praw do obraz­ków: pierw­szego, drugiego, trze­ciego, czwar­tego.

Podobne wpisy:

  1. Wygrze­bane z GitHuba (3) : Validation
  2. Wygrze­bane z GitHuba (4) : PHP User Agent
  3. Wygrze­bane z GitHuba (6) : Monolog
  4. Wygrze­bane z GitHuba (1) : CSS Crush

3 Comments

  • 10 czerwca 2011 - 07:11 | Permalink

    normal­nie czło­wiek prze­cież zapi­suje obrazki najpierw na dysk„
    Napi­sał­bym tylko, że zapi­suje obrazki, nie szcze­gól­nie jest to plik/dysk.

  • starach
    10 czerwca 2011 - 09:27 | Permalink

    ~up: Eeee? No chyba że masz na myśli że mogą jesz­cze być w pamięci. :P

    Bardzo fajny wpis Śpiechu.

  • 10 czerwca 2011 - 09:41 | Permalink

    @starach: rozu­miem uogól­nie­nie, ale bardziej na miej­scu byłby po prostu zapis.
    Można prze­two­rzoną grafikę wrzu­cić prze­cież do pliku, bazy danych, pamięci czy rozpro­szo­nego systemu

  • Dodaj komentarz

    Twój adres e-mail nie zostanie opublikowany.

    Możesz użyć następujących tagów oraz atrybutów HTML-a: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <p> <pre lang="" line="" escaped=""> <q cite=""> <strike> <strong>