Přeskočit obsah

Manipulace s obrázky v CDN

Naše CDN umožňuje on-the-fly manipulaci s obrázky pomocí imgproxy. A to mimo jiné změnu velikosti, změnu formátu, rotaci a úpravu komprese. Takže není potřeba mít u každého obrázku dopředu vygenerované všechny varianty rozměru a formátu ale je možné požadovaný rozměr nebo formát generovat on demand což vede k výrazné úspoře místa na disku.

Použití

Všechny parametry požadovaného obrázku se zakodují do URL a tento request se podepíše pro každého klienta unikátním klíčem, takže request nemůže nikdo podvrhnout a nebo změnit.

Nejjednodušší formát URL na resize obrázku vypadá takto:

example.vshcdn.net/zoh4eiLi/IMG/%TTL/%signature/%resizing_type/%width/%height/%gravity/%enlarge/%encoded_source_url.%extension

Vysvětlení jednotlivých částí URL

  • example.vshcdn.net - název domény, kterou máte nasměrovanou na VshCDN
  • /zoh4eiLi/IMG/ - location která se předává do imgproxy, standardní umístění /imgproxy by mohlo být v kolizi s případnou /imgproxy na zákaznické doméně
  • %TTL - nastavuje jak dlouho se má obrázek cachovat v prohlížeči klienta a na mezilehlých proxy včetně CDN
  • %signature - podpis requestu, hash řetězce kterou může vygenerovat jen ten co zná zákaznický klíč k CDN
  • %resizing_type/%width/%height/%gravity/%enlarge - parametry requestu pro imgproxy; podrobněji vysvětleno v odstavci o podporovaných operacích
  • %encoded_source_url - URL ze které se má stáhnout obrázek který se bude zpracovávat kodovaná v base64
  • %extension - jaký formát má mít výsledný obrázek

Vygenerování podpisu

Pro vygenerování podpisu potřebujeme znát tyto parametry:

  • key: hodnota z administrace - ImgApi Key - (https://cdn.vshosting.cloud/cdndomains => Show details => Current configuration)
  • salt: hodnota z administrace - ImgApi Salt - (https://cdn.vshosting.cloud/cdndomains => Show details => Current configuration)
  • ttl: hodnota %ttl z url
  • path: tato část url: "%resizing_type/%width/%height/%gravity/%enlarge/%encoded_source_url.%extension"

Podpis se poté spočte takto:

$keyBin = pack("H*" , $key);  
$saltBin = pack("H*" , $salt);  
signature = rtrim(strtr(base64_encode(hash_hmac('sha256', $saltBin."/".$ttl."/".$path, $keyBin, true)), '+/', '-_'), '=');

Příklad PHP skriptu pro vygenerování URL na resize obrázku

<?php
$key = ''; // hodnota z administrace - ImgApi Key - (https://cdn.vshosting.cloud/cdndomains => Show details => Current configuration)  

$salt = ''; // hodnota z administrace - ImgApi Salt  
$cdn_domain_or_alias = 'example.vshcdn.net'; // hodnota z administrace CDN Domain Alias nebo CDN domain  
$backend_url = 'https://example.com/obrazek.jpg'; // URL na backend na obrazek  
$ttl = 7200; // nacachování (browser + CDN) na x sekund minimalni hodnota 3600  

// nastavení parametrů resize  
$resize = 'fill';  
$width = 50;  
$height = 50;  
$gravity = 'no';  
$enlarge = 1;  
$extension = 'jpg';  

$keyBin = pack("H*" , $key);  
if(empty($keyBin)) {  
die('Key expected to be hex-encoded string');  
}  
$saltBin = pack("H*" , $salt);  
if(empty($saltBin)) {  
die('Salt expected to be hex-encoded string');  
}  

$encodedUrl = rtrim(strtr(base64_encode($backend_url), '+/', '-_'), '=');  
$path = "/{$resize}/{$width}/{$height}/{$gravity}/{$enlarge}/{$encodedUrl}.{$extension}";  
$signature = rtrim(strtr(base64_encode(hash_hmac('sha256', $saltBin."/".$ttl."/".$path, $keyBin, true)), '+/', '-_'), '=');  

print(sprintf("%s/zoh4eiLi/IMG/%d/%s%s", $cdn_domain_or_alias, $ttl, $signature, $path));

Vlastní název souboru na konci url

V případě, že v URL nahradíme IMG za IMGCU cdn zahodí tu část URL, která je za posledním /, URL potom může vypadat například následovně:

example.vshcdn.net/zoh4eiLi/IMGCU/%TTL/%signature/%resizing_type/%width/%height/%gravity/%enlarge/%encoded_source_url.%extension/mujvlastninazev.jpg

V případě využití funkce smazání cache zadávame následující URL bez poslední části, tzn.:

example.vshcdn.net/zoh4eiLi/IMGCU/%TTL/%signature/%resizing_type/%width/%height/%gravity/%enlarge/%encoded_source_url.%extension

Pokročilé operace

Kromě jednoduchého formátu URL kde implicitní operací je resize tak imgproxy umožňuje provádět i pokročilejší operace. Pro ty se používá následující formát URL.

example.vshcdn.net/zoh4eiLi/IMG/%TTL/%signature/%processing_options/%encoded_source_url.%extension

Parametr %processing_options je složen z jednolivých operací.
Každá operace má formát "%option_name:%argument1:%argument2:...:argumentN" a jednotlivé operace se oddělují lomítkem.

Druhy operací

Rotate

Popis: provede rotaci po směru hodinových ručiček o zadaný počet stupňů.
URL: rotate:%angle
Parametry: angle: o kolik stupňů otočit obrázek, podporovány hodnoty 0,90,180,270

Quality

Popis: sníží kvalitu a tím i velikost vygenerovaného obrázku
URL: quality:%quality
Parametry: quality: procentuelní hodnota kvality v rozmezí 0-100

Max Bytes

Popis: sníží kvalitu obrázku pod zadanou hodnotu, alternativa k operaci Quality
URL: max_bytes:%bytes
Parametry: bytes - maximální velikost vygenerovaného obrázku
Poznámka: aktuálně jsou podporovány jen tyto formáty: jpg, webp, heic, tiff

Blur

Popis: rozmaže obrázek podle nastavené intenzity
URL: blur:%sigma
Parametry: sigma: velikost masky, tedy hodnota sigma pro gausovo rozložení váhy pro barvy okolních pixelů

Resize

Popis: určuje na jaké rozměry změnit obrázek
URL: resize:%resizing_type:%width:%height:%enlarge
Parametry: resizing_type: viz níže
width: výsledná šířka
height: výsledná výška
enlarge: jestli zvětšit obrázek když je požadovaná velikost větší než původní

Resizing type

Popis: určuje chování img proxy při změně velikosti
URL: resizing_type:%resizing_type
Parametry: resizing_type: jakým způsobem provést resize, možné hodnoty jsou tyto:
fit: při zachování poměru stran změní velikost tak že výsledný obrázek je stejný nebo menší než zadaná velikost
fill: zachová poměr stran a ořízne části obrázku aby výsledný obrázek přesně vyplnil zadané rozměry
auto: pokud má nová i původní velikost stejnou orientaci tak použije fill, jinak použije fit

Gravity

Popis: určuje jakou část obrázku se má pokusit zachovat pokud je při resize potřeba odstranit části obrázku
URL: gravity:%type:%x_offset:%y_offset
Parametry:
x_offset: posune výslednou gravitaci v ose X
y_offset: posune výslednou gravitaci v ose Y
type: druh gravitace, tedy jaká část obrázku se zachová, dostupné hodnoty jsou:
   ce: (center) střed
   no: (north) horní hrana
   so: (south) dolní hrana
   ea: (east) pravá hrana
   we: (west) levá hrana
   noea: (north-east) horní pravý roh
   nowe: (north-west) horní levý roh
   soea: (south-east) dolní pravý roh
   sowe: (south-west) dolní levý roh
Poznámka: ještě existují 2 speciální gravitace:
"gravity:sm": chytrá gravitace: imgproxy se pokusí detekovat jaká část obrázku je zajímavá
"gravity:fp:%x:%y": bodová gravitace: hodnoty x,y jsou hodnoty mezi 0 a 1 které určují okolí jaké části obrázku se má prioritě zachovat. Hodnota [0:0] je pravý horní rog a [1:1] je levý spodní roh.

Watermark

Popis: vloží na obrázek vodoznak podle nastavené velikosti, polohy a intenzity 
URL: watermark:%opacity:%position:%x_offset:%y_offset:%scale 
Parametry: 
opacity: průhlednost vodoznaku: hodnotou se vynásobí aktuální průhlednost použitého obrázku 
  position: (volitelné) určení pozice vodoznaku: dostupné hodnoty jsou: 
   ce: (center) střed - výchozí hodnota no: (north) horní hrana 
   so: (south) dolní hrana 
   ea: (east) pravá hrana 
   we: (west) levá hrana 
   noea: (north-east) horní pravý roh 
   nowe: (north-west) horní levý roh 
   soea: (south-east) dolní pravý roh 
   sowe: (south-west) dolní levý roh 
   re: (replicate) replikuje vodoznak, aby vyplnil celý obrázek 
  x_offset: (volitelné) posune výslednou pozici v ose X (nepoužitelné s pozicí typu "re") 
  y_offset: (volitelné) posune výslednou pozici v ose Y (nepoužitelné s pozicí typu "re") 
scale: (volitelné) hodnota vyjádřená desetinným číslem, která určuje relativní velikost vodoznaku k obrázku 

Toto není kompletní výčet všech dostupných operací, ale jen výběr těch nejpoužívanějších. Kompletní seznam se nachází na https://docs.imgproxy.net/#/generating_the_url_advanced.

Kombinování více operací

Máme tyto přístupové údaje:
key = '2387c7e85671cf44'
salt ='9b578a46eacd3b76'

CDN doménu máme "moje_domena.vshcdn.net" a zdroj obrázku je "https://moje_domena.com/obrazek.jpg"
Cachovat obrázek chceme 2h a chceme aby nový obrázek měl rozměny 300x400, kvalitu jen 50% původního, byl otočený o do prava a aby imgproxy sama detekovala jakou část obrázku případně oříznout. Výsledný formát má být moderní webp.

Kodovaná backend URL tedy bude aHR0cHM6Ly9tb2plX2RvbWVuYS5jb20vb2JyYXplay5qcGc

Request URL tedy bude vypadat takto:
/resize:fill:300:400:0/gravity:sm/quality:50/rotate:90/aHR0cHM6Ly9tb2plX2RvbWVuYS5jb20vb2JyYXplay5qcGc.webp

Podpis requestu tedy bude: cnxeUxbuns6P-4OwZBBIMzWxOcGQvaHZHjM1GYYIgXM

A celá URL bude:
https://moje_domena.vshcdn.net/zoh4eiLi/IMG/7200/cnxeUxbuns6P-4OwZBBIMzWxOcGQvaHZHjM1GYYIgXM/resize:fill:300:400:0/gravity:sm/quality:50/rotate:90/aHR0cHM6Ly9tb2plX2RvbWVuYS5jb20vb2JyYXplay5qcGc.webp

Limity v imgproxy

V imgproxy pro manipulaci s obrázky jsou námi nastaveny následující limity:

  • IMGPROXY_READ_TIMEOUT=15
  • IMGPROXY_WRITE_TIMEOUT=15
  • IMGPROXY_DOWNLOAD_TIMEOUT=10
  • IMGPROXY_MAX_SRC_RESOLUTION=30.0

Ostatní limity jsou nastaveny na defaultní hodnoty, které je možnost zjistit v dokumentaci imgproxy