Slovak (Slovenčina) translation by Ondřej Dokoupil (you can also view the original English article)
Vždy si chcel univerzálny, ľahko použiteľnú metódu pre zmenu veľkosti obrázkov v PHP? No na to sú PHP triedy - opakovane použiteľné častí funkcií, ktoré zavoláme pre urobeniu špinavej práce za scénou. Dozvieme sa, ako vytvoriť vlastnú triedu, ktorá bude dobre zostavená, ako aj rozšíriteľná. Zmena veľkosti by mala byť jednoduchá. Ako jednoduchá? Čo tak v troch krokoch!
Úvod
Dám vám rýchly pohľad na to, čoho sa snažíme dosiahnuť s našou triedou, trieda by mala byť:
- Jednoduchá na použitie
- Formátovo nezávislá. Tj. otvoriť, zmeniť veľkosť a uložiť rad rôznych formátov obrázkov.
- Inteligentné nastavenie veľkosti - bez skreslenia obrazu!
Poznámka: Toto nie je návod na vytvorenie triedy a objektov, a hoci by pomohla táto zručnosť, nie je nevyhnutná pre tento kurz.
Je toho veľa k prebratí - začnime.
Krok 1 Príprava
Začneme zľahka. Vo vašom pracovnom adresári vytvorte dva súbory: jeden nazvaný index.php, druhý resize-class.php

Krok 2 Volaním objektu
Dám vám predstavu čoho sa snažíme dosiahnuť, začneme tým, že nakódujeme volanie, ktoré použijeme na zmene veľkosti obrázkov. Otvorte súbor index.php a pridajte nasledujúci kód.
Ako môžete vidieť, je tu logika v tom čo tu robíme. Otvoríme súbor obrázku, nastavili sme rozmery ktoré chceme zmeniť vo veľkosť fotky a typ zmeny veľkosti.
Potom môžeme uložiť obrázok, vyberieme formátu obrazu ktorý chceme a kvalitu obrazu. Uložte a zatvorte súbor index.php.
// *** Include the class include("resize-class.php"); // *** 1) Initialize / load image $resizeObj = new resize('sample.jpg'); // *** 2) Resize image (options: exact, portrait, landscape, auto, crop) $resizeObj -> resizeImage(150, 100, 'crop'); // *** 3) Save image $resizeObj -> saveImage('sample-resized.gif', 100);
V kóde vyššie môžete vidieť že sme otvorili súboru jpg, ale uložili sme ho vo formáte gif. Pamätajte si, že je to všetko o pružnosti.
Krok 3 Triedy kostry
Je to Object-Oriented Programming (OOP), ktorá umožní tento pocit pohody. Myslite na triedy ako na vzor; môžete zapouzdřit dáta - v inom žargóne ten termín znamená skrytie dát. Môžeme využiť túto triedy znovu a znovu bez nutnosti prepisovať zmeny v kóde zmeny veľkosti - potrebujete volať zodpovedajúce metódy, rovnaké ako sú v kroku dve. Akonáhle je náš vzor vytvorený, vytvoríme inštancie tohto vzoru, nazývané objekty.
"Konstrukt funkcií, známi ako konštruktor, sú špeciálna metóda tried, ktorá získava volanú triedu, keď vytvoríte nový objekt."
Začnime, vytvorením našej resize triedy. Otvorte súbor resize-class.php. Nižšie je naozaj základná kostra štruktúry triedy, ktorú som pomenoval "resize". Všimnite si riadku triedy premenné s komentárom; to je miesto kde začneme neskôr pridávať pre nás dôležité triedy premenných.
Funkcia konštrukcia, známa ako konštruktor, je špeciálny trieda metódy (termín "method" je rovnaká ako funkcia, Avšak, keď hovoríme o triedach a objektoch, termín metóda sa často používa), ktorá volá triedu, keď vytvoríte nový objekt. Vďaka tomu je pre nás vhodné urobiť nejaké inicializácia - urobíme ich v ďalšom kroku.
Class resize { // *** Class variables public function __construct() { } }
Všimnite si, že je dvojité podčiarknik pre metódu konštrukcie.
Krok 4 Konštruktor
Chceme zmeniť metódu konstruktoru vyššie. Po prvé, zrušíme meno súboru (a cestu) vášho obrázka sa veľkosť. Zavoláme premenou $ fileName.
Potrebujeme otvoriť súbor prenášaný prostredníctvom PHP (presnejšie povedané GD knižnica PHP) takže PHP môže čítať obrázok. Robíme to s vlastnou metódou "openImage". Dostanem sa k tomu ako metóda
funguje za chvíľu, ale zatiaľ, musíme uložiť výsledok ako premenné triedy. Premenná triedy je premenná - ale to je špecifické pre danú triedu. Pamätajte si komentár premenné triedy, o ktorom som sa zmienil skôr? Přidejtete 'image' ako súkromnú premennú zadaním "private $ imidž;". Nastavením premennej ako "Private" si nastavíte pôsobnosti danej premennej, takže ju možno sprístupniť iba triedou. Odteraz môžeme zavolať náš otvorený obraz, známy ako prostriedok, ktorý budeme potrebovať neskôr keď budeme meniť veľkosť.
Keď už sme pri tom, tak vyplňte výšku a šírku obrázku. Mám pocit, že to bude neskôr užitočné.
Teraz by ste mali mať nasledujúce.
Class resize { // *** Class variables private $image; private $width; private $height; function __construct($fileName) { // *** Open up the file $this->image = $this->openImage($fileName); // *** Get width and height $this->width = imagesx($this->image); $this->height = imagesy($this->image); } }
Metódy imagesx a Images sú postavené vo funkciách, ktoré sú súčasťou knižnice GD. Získajú šírku a výšku vášho obrazu, respektíve.
Krok 5 Otvorenie obrázku
V predchádzajúcom kroku, sme volali vlastnú metódu openImage. V tomto kroku budeme vytvárať túto metódu. Chceme po skriptu aby za nás premýšľal, takže podľa toho, aký typ súboru je mu odovzdaný, skript by mal určiť, akú funkciu GD knižnice volá pre otvorenie obrázku. To sa dá ľahko dosiahnuť porovnaním rozšírenia súborov pomocou príkazu switch.
Zrušili sme v našom súbore čo chceme prevzorkovat a vrátili sme výsledok súboru.
private function openImage($file) { // *** Get extension $extension = strtolower(strrchr($file, '.')); switch($extension) { case '.jpg': case '.jpeg': $img = @imagecreatefromjpeg($file); break; case '.gif': $img = @imagecreatefromgif($file); break; case '.png': $img = @imagecreatefrompng($file); break; default: $img = false; break; } return $img; }
Krok 6 Ako zmeniť veľkosť
To je to čo si zamilujete. Tento krok je naozaj len vysvetlenie toho, čo budeme robiť - takže žiadne úlohy. V ďalšom kroku musíme vytvoriť verejnú metódu, ktorá budeme volať na vykonávanie našej veľkosti; tak to dáva zmysel pre odovzdávanie v Šírka a výška, rovnako ako informácie o ako chceme zmeniť veľkosť obrázka. Porozprávajme sa o tom za chvíľu. Bude existovať scenár, kde chcete zmeniť veľkosť obrázka na presnú veľkosť. Skvelé, tak to patrí. Ale bude tiež chvíľa, kedy budete musieť zmeniť veľkosť stovky snímok a každý obrázok má iný pomer strán - napríklad portrétne snímky. Zmena veľkosti na presnú veľkosť spôsobí závažné skreslenia. Ak sa pozrieme na naše možnosti, aby nedošlo ku skresleniu môžeme:
- Veľkosť obrazu tak blízko, ako môžeme na naše nové rozmery obrázku a zachovať pomer strán.
- Zmeniť veľkosť obrázku, tak blízko, ako môžeme na naše nové rozmery obrazu a oreže zostávajúce.
Obe možnosti sú životaschopné, podľa vašich potrieb.
Jo. budeme sa pokúšať spracovávať všetky vyššie uvedené. Pre pripomenutie, budeme poskytovať možnosti:
- Zmeniť veľkosť na presnú šírku / výšku. (presný)
- Zmena veľkosti podľa šírky - presná šírka bude nastavená, bude upravená výška podľa pomeru strán. (na šírku)
- Zmena veľkosti podľa výšky - ako zmeniť veľkosť šírky, ale nastaví sa výška a dynamicky sa upraví šírka. (na výšku)
- Automaticky určiť možnosti 2 a 3. Ak prechádzate zložky s fotografiami rôznych veľkostí, či skriptu určí, ako to urobí. (auto)
- Zmena veľkosti a orezanie. To je moja obľúbená. Presná veľkosť, bez skreslenia. (orezanie)
Krok 7 Zmena veľkosti. Ideme na to!
Existujú dve časti převzorkovací metódy. Prvý nastavuje optimálny šírku a výšku pre náš nový obrázok vytvorením nejaké vlastné metódy - a samozrejme odovzdanie našej veľkosti "možnosti" ako je popísané vyššie. Šírka a výška sú vrátené ako pole a nastavenie ich príslušných premenných. Nebojte sa "pass as referencie" - ale ja nie som toho veľký fanúšik.
Druhá časť je čo robí so skutočnou veľkosťou. V záujme zachovania tohto kurzu zníženie veľkosť, dám vám prečítať o nasledujúce funkcii GD:
- imagecreatetruecolor
- imagecopyresampled
Tiež sme uložili výstup metódy imagecreatetruecolor (a new true color image) ako premenné triedy. Pridať 'private $ imageResized;' s vašou inou premennou triedou.
Zmena veľkosti sa vykonáva pomocou PHP modul, ktorý je známy ako GD knižnice. Mnoho metód, ktoré používame sú k dispozícii v tejto knižnici.
// *** Add to class variables private $imageResized;
public function resizeImage($newWidth, $newHeight, $option="auto") { // *** Get optimal width and height - based on $option $optionArray = $this->getDimensions($newWidth, $newHeight, strtolower($option)); $optimalWidth = $optionArray['optimalWidth']; $optimalHeight = $optionArray['optimalHeight']; // *** Resample - create image canvas of x, y size $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight); imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height); // *** if option is 'crop', then crop too if ($option == 'crop') { $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight); } }
Krok 8 Rozhodovací strom
Čím viac práce, ktorú robíte teraz, tým menej musíte urobiť pri zmene veľkosti. Táto metóda vyberie trasu prijatí s cieľom získať optimálnu veľkosť šírky a výšky založenú na možnosti prevzorkovanie. To bude volať zodpovedajúce metódu, ktorú budeme vytvárať v ďalšom kroku.
private function getDimensions($newWidth, $newHeight, $option) { switch ($option) { case 'exact': $optimalWidth = $newWidth; $optimalHeight= $newHeight; break; case 'portrait': $optimalWidth = $this->getSizeByFixedHeight($newHeight); $optimalHeight= $newHeight; break; case 'landscape': $optimalWidth = $newWidth; $optimalHeight= $this->getSizeByFixedWidth($newWidth); break; case 'auto': $optionArray = $this->getSizeByAuto($newWidth, $newHeight); $optimalWidth = $optionArray['optimalWidth']; $optimalHeight = $optionArray['optimalHeight']; break; case 'crop': $optionArray = $this->getOptimalCrop($newWidth, $newHeight); $optimalWidth = $optionArray['optimalWidth']; $optimalHeight = $optionArray['optimalHeight']; break; } return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); }
Krok 9 Optimálne rozmery
Už sme už prebrali, čo tieto štyri metódy robia. Je tu len základné matematika, naozaj, vypočítava naši najlepší zhodu.
private function getSizeByFixedHeight($newHeight) { $ratio = $this->width / $this->height; $newWidth = $newHeight * $ratio; return $newWidth; } private function getSizeByFixedWidth($newWidth) { $ratio = $this->height / $this->width; $newHeight = $newWidth * $ratio; return $newHeight; } private function getSizeByAuto($newWidth, $newHeight) { if ($this->height < $this->width) // *** Image to be resized is wider (landscape) { $optimalWidth = $newWidth; $optimalHeight= $this->getSizeByFixedWidth($newWidth); } elseif ($this->height > $this->width) // *** Image to be resized is taller (portrait) { $optimalWidth = $this->getSizeByFixedHeight($newHeight); $optimalHeight= $newHeight; } else // *** Image to be resizerd is a square { if ($newHeight < $newWidth) { $optimalWidth = $newWidth; $optimalHeight= $this->getSizeByFixedWidth($newWidth); } else if ($newHeight > $newWidth) { $optimalWidth = $this->getSizeByFixedHeight($newHeight); $optimalHeight= $newHeight; } else { // *** Sqaure being resized to a square $optimalWidth = $newWidth; $optimalHeight= $newHeight; } } return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); } private function getOptimalCrop($newWidth, $newHeight) { $heightRatio = $this->height / $newHeight; $widthRatio = $this->width / $newWidth; if ($heightRatio < $widthRatio) { $optimalRatio = $heightRatio; } else { $optimalRatio = $widthRatio; } $optimalHeight = $this->height / $optimalRatio; $optimalWidth = $this->width / $optimalRatio; return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight); }
Krok 10 Orezanie
Ak ste sa rozhodla pre "crop" - to znamená, že ste použili možnosť orezanie, potom máte o ďalší malý krok navyše. Ideme orezať obrázok od
stredu. Orezanie je veľmi podobný proces zmeny veľkosti, ale s pár na viac nastavení parametra veľkostí.
private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight) { // *** Find center - this will be used for the crop $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 ); $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 ); $crop = $this->imageResized; //imagedestroy($this->imageResized); // *** Now crop from center to exact requested size $this->imageResized = imagecreatetruecolor($newWidth , $newHeight); imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight); }
Krok 11 Uloženie obrázka
Dostávame sa tam; takmer hotovo. Teraz je čas na uloženie obrázku. Ďalším krokom je akú kvalitu obrazu by sme radi v rozmedzí od 0-100, 100 je najlepší a zavoláme zodpovedajúce metódy. Pár postrehov o kvalite obrazu: JPG používa škále od 0-100, 100 je najlepší. GIF obrázky nemajú nastavenia kvality obrazu. PNG má, ale používa sa stupnica 0-9, 0 je najlepšia. To nie je dobré, predsa nemôžeme od nás očakávať si to budeme pamätať zakaždým, keď chceme uložiť obrázok. Urobíme trochu kúzlo a všetko štandardizujeme.
public function saveImage($savePath, $imageQuality="100") { // *** Get extension $extension = strrchr($savePath, '.'); $extension = strtolower($extension); switch($extension) { case '.jpg': case '.jpeg': if (imagetypes() & IMG_JPG) { imagejpeg($this->imageResized, $savePath, $imageQuality); } break; case '.gif': if (imagetypes() & IMG_GIF) { imagegif($this->imageResized, $savePath); } break; case '.png': // *** Scale quality from 0-100 to 0-9 $scaleQuality = round(($imageQuality/100) * 9); // *** Invert quality setting as 0 is best, not 9 $invertScaleQuality = 9 - $scaleQuality; if (imagetypes() & IMG_PNG) { imagepng($this->imageResized, $savePath, $invertScaleQuality); } break; // ... etc default: // *** No extension - No save. break; } imagedestroy($this->imageResized); }
Teraz je tiež vhodná doba k zničeniu nášho zdroja obrazu pre uvoľnenie pamäte. Ak by ste to chceli použiť v produkcii, môže to byť vhodné na zachytenie a vrátenie výsledku uloženého obrazu.
Záver
No a je to, priatelia. Ďakujem Vám za prejdení tohto kurzu, dúfam, že vám to bolo užitočné. Ocenil by som vašu spätnú väzbu, a to prostredníctvom nižšie uvedených komentárov.
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post