Utils\Image auto orientace obrázku

dms
Člen | 87
+
+4
-

Šla by přidat funkce na automatické otočení obrázku dle exif dat do nette utils?
Konkrétně jde o tuto funkci kterou mají ostatní image procesory viz např:

https://github.com/…eCommand.php

nebo

https://github.com/…pleImage.php#L501

Je to jediné co mi v nette image zpracování obrázku chybí a používáme to velmi často pak právě s jinou knihovnou. Obrázky z iPhonu jsou jinak často obráceně. Jelikož to dáváme do každého projektu a podle mě nejsem jediný kdo to řeší tak měla by takováto funkce opodstatnění? Klidně bych udělal PR.

David Grudl
Nette Core | 8099
+
+3
-

Jo, tak pošli PR.

dms
Člen | 87
+
+1
-

Funkce je hotová. Má to však jeden háček který nevím jak jinak obejít než přidat novou property do Image. exif_read_data to není schopné přečíst z resource ale pouze z cesty k souboru nebo streamu. Nějaký nápad jak se tomu vyhnout a načíst exif data přímo ve funkci z resource?

/** @var string */
private $path;

tahle property by se musela přidat a pak upravit konstruktor následovně

public function __construct($image, $path = null)
{
	$this->setImageResource($image);
	$this->path = $path;
	imagesavealpha($image, true);
}

potom finální funkce která otočí a případně převrátí image

public function fixOrientation()
{
    if (!function_exists('exif_read_data')) {
        throw new Nette\NotSupportedException('PHP extension Exif is not loaded.');
    }

    $type = self::detectTypeFromFile($this->path);

    if (self::typeToMimeType($type) !== 'image/jpeg') {
        return $this;
    }

    $exif = exif_read_data($this->path);

    if (!isset($exif['Orientation'])) {
        return $this;
    }

    $orientation = (int)$exif['Orientation'];

    if (in_array($orientation, [3, 4])) {
        $this->image = imagerotate($this->image, 180, 0);
    } elseif (in_array($orientation, [5, 6])) {
        $this->image = imagerotate($this->image, -90, 0);
    } elseif (in_array($orientation, [7, 8])) {
        $this->image = imagerotate($this->image, 90, 0);
    }

    if (in_array($orientation, [2, 5, 7, 4])) {
        $this->flip(IMG_FLIP_HORIZONTAL);
    }

    return $this;
}

otestováno na těchto příkladech a všechny výsledky jsou ok https://github.com/…ion-examples

mittermichal
Člen | 1
+
0
-

@dms ahoj, co tak to urobit ako staticku metodu s povinnymi parametrami Image a path?

David Grudl
Nette Core | 8099
+
+1
-

Super!

Metodu bych nechal nestatickou, a parametr $path by se předával do ní, co?

Milo
Nette Core | 1283
+
0
-

dms napsal(a):

Funkce je hotová. Má to však jeden háček který nevím jak jinak obejít než přidat novou property do Image. exif_read_data to není schopné přečíst z resource ale pouze z cesty k souboru nebo streamu.

Manuál tvrdí, že to umí EXIF data číst i z resource. https://www.php.net/…if-read-data

Teď mi došlo, že tím resource je myšleno stream resource. Tak nic :)

dms
Člen | 87
+
0
-

Bohužel ta funkce je hloupá no :) ale napadlo mě převést GD resource na stream přes php://memory a pak to zkusit poslat do exif funkce. Vyzkouším a kod případně upravím

David Matějka
Moderator | 6445
+
0
-

Jaký výkonnostní dopad by mělo číst ta exif data rovnou v fromString / fromFile metodách? Případně s nějakým flagem v parametrech metody.

dms
Člen | 87
+
0
-

Pak by objekt Image měl mít property $exif do které by se to uložilo při načtení. Výkonnostní dopad tam určitě nějaký bude. To by zas bylo potřeba vyzkoušet jak moc to dává, či nedává smysl donačítat lazy až v případě potřeby nebo načíst hned