Nette\Image – získání typu načteného obrázku

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

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
+
0
-

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
+
0
-

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.

toka
Člen | 253
+
0
-

Tak šlo by pro vlastní potřebu upravit Nette\Image. Aby si při fromFile() do proměnné uložila typ a pak ho použila při save().

VeN
Člen | 46
+
0
-

toka napsal(a):

Tak šlo by pro vlastní potřebu upravit Nette\Image. Aby si při fromFile() do proměnné uložila typ a pak ho použila při save().

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
+
0
-

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');
VeN
Člen | 46
+
0
-
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];
}
toka
Člen | 253
+
0
-

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

Patrik Votoček
Člen | 2221
+
0
-

tak to hodte jako ISSUE na github ne? at muzeme VOTOvat… :-)

toka
Člen | 253
+
0
-

vrtak-cz napsal(a):

tak to hodte jako ISSUE na github ne? at muzeme VOTOvat… :-)

GitHub Issue