Nette\Image – získání typu načteného obrázku
- VeN
- Člen | 46
Ahoj, rád bych se zeptal, jak se dá získat typ (jpg, png, gif…) načteného obrázku. Ve třídě samotné se mi nic takového nedaří nalézt. Obrázek sice v pohodě načtu pomocí metody fromFile, ale mám problém při jeho uložení (nepoužívám příponu), metoda save typ požaduje, v případě, že typ nevyčte z názvu souboru.
- redhead
- Člen | 1313
Nejsem si tím 100% jist, ale podle mě načtený obrázek v Image jsou prostě jen obrazová data (bez žádného formátu) a až při jeho uložení se převede do požadovaného formátu.
A když vlastně víš z jakého obrázku to tvoříš, tak víš
i formát, který při save předáš, ne?
Editoval redhead (23. 8. 2010 13:04)
- VeN
- Člen | 46
Právě že to nevím. Metoda Nette\Image::fromFile() bere jenom cestu k souboru a informace si zjišťuje pomocí funkce getimagesize. A metoda fromFile typ obrázku nikam neukládá, ani ho nikam nevrací. Já dostanu instanci Nette\Image s image resourcem, který je opravdu tvořen surovými daty.
Já s touhle instancí provedu resize a následný uložení (název souboru neobsahuje příponu s typem). Očekával bych, že když si Nette\Image dokáže soubor načíst, aniž bych specifikoval typ, tak že ho v tom samém typu dokáže uložit. Bohužel nedokáže, protože počítá s tím, že soubor pojmenuji tak, že bude obsahovat příponu.
Dokážu to samozřejmě obejít vlastním voláním funkce getimagesize, ale to mi přijde jako zbytečné duplikování kódu.
- VeN
- Člen | 46
toka napsal(a):
Tak šlo by pro vlastní potřebu upravit
Nette\Image
. Aby si přifromFile()
do proměnné uložila typ a pak ho použila přisave()
.
Jo, to šlo :) Ale myslím, že by tohle měl dělat už Nette\Image sám, protože takhle buď musím přepsat přímo Nette\Image, nebo si naimplementovat vlastní Image třídu, odvozenou od Nette\Image. Druhé řešení je samozřejmě lepší, ale stejně ve mně zanechává dojem, že dělám něco, co by dělat původní třída.
- toka
- Člen | 253
Upravil bych Image
např. následovně:
...
/** @var string */
public static $imageType;
...
public static function fromFile($file, & $format = NULL)
{
if (!extension_loaded('gd')) {
throw new Exception("PHP extension GD is not loaded.");
}
$info = @getimagesize($file); // intentionally @
if (self::$useImageMagick && (empty($info) || $info[0] * $info[1] > 9e5)) { // cca 1024x768
return new ImageMagick($file, $format);
}
self::$imageType = strtolower(pathinfo($file, PATHINFO_EXTENSION));
switch ($format = $info[2]) {
case self::JPEG:
return new self(imagecreatefromjpeg($file));
case self::PNG:
return new self(imagecreatefrompng($file));
case self::GIF:
return new self(imagecreatefromgif($file));
default:
if (self::$useImageMagick) {
return new ImageMagick($file, $format);
}
throw new Exception("Unknown image type or file '$file' not found.");
}
}
...
public function save($file = NULL, $quality = NULL, $type = NULL)
{
if ($type === NULL) {
$extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if(!$extension) {
$extension = self::$imageType;
$file .= '.' . $extension;
}
switch ($extension) {
case 'jpg':
case 'jpeg':
$type = self::JPEG;
break;
case 'png':
$type = self::PNG;
break;
case 'gif':
$type = self::GIF;
}
}
switch ($type) {
case self::JPEG:
$quality = $quality === NULL ? 85 : max(0, min(100, (int) $quality));
return imagejpeg($this->getImageResource(), $file, $quality);
case self::PNG:
$quality = $quality === NULL ? 9 : max(0, min(9, (int) $quality));
return imagepng($this->getImageResource(), $file, $quality);
case self::GIF:
return $file === NULL ? imagegif($this->getImageResource()) : imagegif($this->getImageResource(), $file); // PHP bug #44591
default:
throw new Exception("Unsupported image type.");
}
}
...
Vyzkoušel jsem, a funguje. Nezkoušel jsem ale nijak důkladně :-)
$image = Image::fromFile(WWW_DIR . '/images/obrazek.png');
$image->resize(100, NULL, Image::ENLARGE);
$image->save(WWW_DIR . '/images/maly_obrazek');
- toka
- Člen | 253
VeN napsal(a):
self::$imageType = strtolower(pathinfo($file, PATHINFO_EXTENSION));
Díky. Já bych to ještě upravil tak, aby ani při načtení nebyla vyžadována přípona souboru.
if (isset($info[2])) { self::$imageType = $info[2]; }
Však to byl jen nástřel, uprav si jak potřebuješ :-D