Vyhledávání obrázků přes Flickr API v PHP

V tomto článku bych rád popsal napojení na Flickr API pomocí jazyka PHP. Nad obrázky, které pak získáme lze dělat jakákoliv magie, použité aplikační rozhraní nám však poskytne i filtrování, které využijeme. V této konkrétní implementaci budu provádět akorát načítání obrázků, jejich filtrování a třídění dle barvy (což není součástí API).

Výsledná aplikace běží na adrese: http://flickr.7ka.cz/

Zdrojové kódy jsou umístěny: https://github.com/vojtasvoboda/FlickrSearch

Co je nutné před vlastní implementací:

  • Vytvořit si Flickr účet a vygenerovat si KEY, se kterým budeme přistupovat přes API
  • Zajistit, aby požadavky na API byly pouze v UTF-8 kódování
  • Podle toho, jestli budeme ukládat dočasné soubory na disk, nebo do databáze, je potřeba zajistit povolený fopen() na hostingu, nebo zřízenou databázi

Vlastní implementace:

Vzhledem k tomu, že klientskou část implementujeme v jazyku PHP, budeme využívat třídu phpFlickr., která je ke stažení na http://code.google.com/p/phpflickr/.

Tato třída poskytuje abstraktní vrstvu nad API, takže voláme přímo metody API, dále pak několik pomocných funkcí. phpFlickr se nám postará o sestavení korektního XML dotazu a zpracování odpovědi. Takto lze volat všechny metody API, my však využijeme pouze některé z nich:

  • enableCache - touto funkcí si nastavíme lokální cache, abychom při řazení nemuseli fotky opakovaně načítat
  • photos_search() - volá službu flickr.photos.search - tato funkce nám vrátí kolekci fotek dle zadaného klíčového slova
  • buildPhotoURL() - tato funkce nám zjistí korektní URL adresu obrázku
  • getErrorMsg() - zajistí nám chybovou hlášku v případě nějaké chyby
  • photos_getInfo() - funkce vrátí informace o obrázku dle zadaného id

Postup zpracování načtených obrázků

Pomocí funkcí photos_search() a photos_getInfo() získáme kolekci obrázků a informace k nim. Počet načtených obrázků jsem omezil na 24 s tím, že další obrázky jsou dostupně pomocí stránkování, které nám poskytuje přímo API Flickru. Dále musíme obrázky seřadit, což provedeme pomocí PHP funkce usort, která má dva parametry. Jedním je pole obrázků, které chceme seřadit, druhý parametr je porovnávací funkce, která nám vrátí, jestli je jeden prvek menší, nebo větší než druhý. Tuto porovnávací funkci musíme implementovat samostatně, ale vzhledem k tomu, že vždy porovnáváme řetězce, nebo čísla vystačíme si se základními funkcemi PHP.

Filtrování pomocí barvy

Pro filtrování pomocí barvy nejdříve potřebujeme získat barevné spektrum z obrázku. Na to použijeme funkci z tohoto zdroje:

http://www.brandnoo.com/2007/06/26/image-color-analysis-php-code/

Tato funkce nám umožňuje rozdělit obrázek do pomyslné matice, např. 3x3 a pro každý prvek matice vypočte průměrnou barvu, jako trojici čísel R (Red), G (Green), B (Blue).

Nyní je potřeba vymyslet algoritmus, který projde všechny obrázky a určí, který vyhovuje vyhledávané barvě nebo nikoli.
Pokud nastavím výše uvedenou funkci tak, aby vrátila pouze jeden bod (tj. nastavení matice 1x1) dostanu pouze jednu trojici RGB a již můžu pomocí jednoduché funkce určit, jestli obrázek vyhovuje, nebo ne. Například pro červenou:

if ( ($red > $green) & ($red > $blue) ) {
   return true;
}

Po trošce experimentování jsem algoritmus ještě mírně upravil, aby hledaná barvy opravdu převažovala:

if ( ($red > (1.3 * $green)) & ($red > (1.3 * $blue)) ) {
   return true;
}

Takto algoritmus již vrací celkem přijatelné výsledky a nejlépe funguje u obrázků, kde hledaná barva převažuje po celé ploše, např. vyhledávání fráze one color.