Nette\Image dynamicky obrázek pro img src

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

Zdravím.
Chtěl bych pro každého uživatele generovat vlastní obrázek (obrázek nepotřebuji ukládat na disk – zbytečně by zabíral místo – každým vygenerováním bude jiný).

    public function actionUserPicture()
    {
...
        $image = Image::fromBlank( 500, 300, Image::rgb( 200, 200, 200 ) );

        $font_path = '../www/fonts/arial.ttf';
        $image->ttfText(20, 0, 10, 100, Nette\Image::rgb(0, 0, 0), $font_path, "Vaše umístění: ".$position );

        $image->send( Image::PNG );
    }
<img src="/homepage/user-picture">

Tento kod mi obrázek do stránky vygeneruje ale zároveň v konzoli prohlížeče vidím:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)

ale když dám do prohlížeče: …cz/homepage/user-picture tak obrázek vidím a žádná chyba nenastane.

Poradil by někdo jak to dělat správně?

Díky

Badaboom
Člen | 33
+
0
-

Zkus po odeslání obrázku ukončit aplikaci. Imho pokračuje vykreslování šablony, ta neexistuje a proto error.

...
$this->send();
$this->terminate();

jak to dělat správně bych řekl, že imho spouštět kvůli generování obrázků framework je zbytečný plýtvání zdrojů. Zobrazením n obrázků na stránce spouštíš aplikaci n + 1×.

Vyčlenit to by neměl být problém. Nevím s jakými proměnnými u obrázku pracuješ (vidím jenom position), ale ty lze posílat přes parametry.

enumag
Člen | 2118
+
0
-

motorcb napsal(a):
Poradil by někdo jak to dělat správně?

https://api.nette.org/…ter.php.html#… + https://api.nette.org/…esponse.html

Editoval enumag (21. 10. 2013 9:37)

motorcb
Člen | 552
+
0
-

@enumag:

Díky za nakopnutí :-)

sendResponse(Application\IResponse $response)

Ale kde vezmu $response typu Application\IResponse?

enumag
Člen | 2118
+
0
-

@motorcb: Koukals na ten druhý odkaz? :-P

Jo a jinak tu byly i pokusy o nějakou ImageResponse, když budeš googlit tak možná najdeš i nějakou aktuální. Nicméně FileResponse + Image::__toString() by mělo stačit.

Editoval enumag (21. 10. 2013 11:29)

motorcb
Člen | 552
+
0
-

@enumag:

ano, koukal. V presenteru mohu zavolat:

$this->sendResponse( $image->toString() );

Jenže ten mi hlásí: Argument 1 passed to Nette\Application\UI\Presenter::sendResponse() must be an instance of Nette\Application\IResponse, string given

Jak z obrázku udělám instanci Nette\Application\IResponse?

jsvelta
Člen | 39
+
0
-

Jak z obrázku udělám instanci Nette\Application\IResponse?

Vytvor si triedu, ktorá implementuje rozhranie \Nette\Application\IResponse a implementuj metódu send(). Ako inšpiráciu by som použil FileResponse a TextResponse.

motorcb
Člen | 552
+
0
-

@jsvelta:

Díky za nakopnutí :-)

Problém ovšem stále přetrvává.
PictureWall.php

use Nette\Image;

class WallPicture extends Nette\Object implements Nette\Application\IResponse
{

    public function toString()
    {
        $image = Image::fromBlank( 500, 300, Image::rgb( 200, 200, 200 ) );

        $font_path = '../www/fonts/arial.ttf';
        $image->ttfText(20, 0, 10, 100, Nette\Image::rgb(0, 0, 0), $font_path, "Umístění: 1" );

        $image->send( Image::PNG );
    }

    public function send( Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse )
    {

    }
}

Action:

public function actionUserPicture()
{
    $wallPicture = new \WallPicture();
    $this->sendResponse( $wallPicture->toString() );
}

Zobrazení obrázku:

<img src="/homepage/user-picture">

Zobrazí obrázek ale hlásí stále chybu: **GET …/homepage/user-position-picture 500 (Internal Server Error) **
Když zobrazím url v prohlížeči: …/homepage/user-position-picture obázek se zobrazí bej kakékoliv chyby :-(

vvoody
Člen | 910
+
0
-

:D posledné týždne také perly na fóre. Bojím sa ťa poslať do log adresára lebo aj tak by ti ta chybová hláška nič nepovedala. Proste odstráň to volanie toString.

edit: jo aha, ja som sa ani nepozrel na tu tvoju implementáciu IResponse :D celé zle toto. Obsah toString daj do send. Alebo ho tam zavolaj.

Editoval vvoody (21. 10. 2013 17:21)

jsvelta
Člen | 39
+
0
-

Skús takto:

use Nette\Image;
use Nette;

class WallPicture extends Nette\Object implements Nette\Application\IResponse
{

    public function send( Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse )
    {
        $image = Image::fromBlank( 500, 300, Image::rgb( 200, 200, 200 ) );

        $font_path = '../www/fonts/arial.ttf';
        $image->ttfText(20, 0, 10, 100, Nette\Image::rgb(0, 0, 0), $font_path, "Umístění: 1" );

        $image->send( Image::PNG );
    }
}

Action:

public function actionUserPicture()
{
    $wallPicture = new \WallPicture();
    $this->sendResponse( $wallPicture );
}

A ešte by som použil $httpResponse->setContentType(‚image/png‘);

enumag
Člen | 2118
+
0
-

motorcb napsal(a):

@enumag:

ano, koukal. V presenteru mohu zavolat:

$this->sendResponse( $image->toString() );

Jenže ten mi hlásí: Argument 1 passed to Nette\Application\UI\Presenter::sendResponse() must be an instance of Nette\Application\IResponse, string given

Jak z obrázku udělám instanci Nette\Application\IResponse?

No myslel jsem to takhle, to nefunguje?

$this->sendResponse(new FileResonse($image->toString()));
jsvelta
Člen | 39
+
0
-

enumag napsal(a):

No myslel jsem to takhle, to nefunguje?

$this->sendResponse(new FileResonse($image->toString()));

Nefunguje, FileResponse očakáva názov súboru, nie jeho obsah.

Editoval jsvelta (21. 10. 2013 19:16)

enumag
Člen | 2118
+
0
-

@jsvelta: Aha, máš pravdu. :-) Takže bude opravdu nutné napsat vlastní ImageResponse, ale to by neměl být problém.

@motorcb: Pokud ti to hází pětikilo, mrkni do logu.

Editoval enumag (21. 10. 2013 19:58)