Práce s obrázky jako s cache, ImageStorage

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Oggy
Člen | 306
+
0
-

Řeším lazy loading různých rozměrů obrázku.
Mám napsaný helper

<?php
	{$actuality['picture_path']|image:600,400,'alt',FALSE,FALSE,....}
?>

Kde se mi podle nastavených parametrů (šířka,výška,zda ořezávat,zda vkládat watermark apod.) helper podívá, jestli takový soubor již neexistuje a pokud ne, tak mi jej vygeneruje a uloží do filesystemu se jménem generovaným podle názvu a parametrů atd.

Tohle funguje dobře. Asi by to mělo být spíše makro než helper. Ale to není teď podstatné.

Jsem líný a pokud mažu v tomto případě $actuality.. musím ve složce, kam se náhledy ukládají smazat všechny vygenerované náhledy spolu s původním obrázkem.
Tohle by bylo ideální, kdyby fungovalo stejně jako cache.. navážují ji na původní soubor a ona se mi při změně nebo smazání původního souboru postará o invalidaci vygenerovaných náhledů.

Takže jsem helper přepsal, tak aby žádné soubory neukládal, ale předával je cachi, ať se o to postará. Helper vrací objekt Html::el(img) .. jak tady naložit s atributem src? když žádný soubor ve file systému neexistuje? .. napadá mě jedině použív DataStream .

<?php
$img = \Nette\Utils\Html::el('img');
$img->src = \Nette\Templating\Helpers::dataStream($image->toString($format));
$img->width = $image->width;
$img->height = $image->height;
$img->alt = $alt;
$img->title = $title;
if ($class) $img->class = $class;
if ($id) $img->id = $id;

return $img;
?>

což funguje ..ale datastream mi nepřijde pro nepodporuju starších ie ideální.

Otázku, kterou řeším je, jestli pro tento účel jde použít FileStorage nebo jej přepsat do např. ImageStorage?

Nebo na to jdu úplně špatnou cestou?

Shrnutí:
Práce s náhledy obrázků stejně jako s cachí, nestarat se o jejich mazání (invalidaci) ručně, ale navázat jej na původní soubor, při jehož změně dojde k invalidaci vytvořených náhledů.

mkoubik
Člen | 728
+
0
-

Já na tohle používám odkazy na ImagePresenter který změní rozměry a odešle obrázek a k tomu nette cache kam ukládám výsledek $image->toString(). Výhoda je, že akci Image:show si můžeš naroutovat na libovolnou adresu, třeba něco jako /images/100x100/krasne-url.jpeg a nezajímá tě kde je a jak se jmenuje skutečný soubor (může být třeba v db).

Oggy
Člen | 306
+
0
-

@mkoubik a není to pomalé? při každém požadavku na obrázek se musí načíst celé nette.

Honza Marek
Člen | 1664
+
0
-

Svoje řešení naznačím dvěma odkazama. Když budu mít náladu, tak to zkusím vykuchat z již nevyvíjeného Neuronu a dát tomu třeba vlastní repozitář.

bene
Člen | 82
+
0
-

Řeším to podobně jako @mkoubik, akorát cache = uložený resizovaný obrázek na disku, kde má přístup apache. Pak jen upravím v .htaccess, aby pokud obrázek (soubor) neexistuje, pustím ho do presenteru, kde se vygeneruje, uloží a pošle na výstup. Příští request už jde přímo na existující soubor.

Oggy
Člen | 306
+
0
-

bene napsal(a):

Řeším to podobně jako @mkoubik, akorát cache = uložený resizovaný obrázek na disku, kde má přístup apache. Pak jen upravím v .htaccess, aby pokud obrázek (soubor) neexistuje, pustím ho do presenteru, kde se vygeneruje, uloží a pošle na výstup. Příští request už jde přímo na existující soubor.

To ano, ale tady nefunguje to, že pokud se změní obrázek původní neinvalidují se (nesmažou se vygenerované náhledy, nebo ano?

jtousek
Člen | 951
+
0
-

@Oggy: Moc hezké. Já sám to řeším pomocí makra, ovšem mazání starých náhledů jsem jednoduše neřešil. Že to není ideální vím už dlouho ale nebyl čas. Použít cache mě napadlo také, takže myslím že na to jdeš správně. Myslím také, že by to měla být samostatná třída ImageStorage. Měla by např. kontrolovat, že ta cache je přístupná z prohlížeče, tj. je vygenerován .htaccess a celá složka není zahrabaná někde pod document_root.