欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Laravel generate image and add content type header

Hi I'm using php's gd library to generate images. I've decided to integrate this into laravel, and I managed to make it work.

My problem is that if laravel sometimes overwrites my content-type header.

This is my controller:

public function imga($algorythm,$w=false,$h=false){
    if (!$w) $w=rand(250,750);
    if (!$h) $h=rand(250,750);
    $im = imagecreatetruecolor($w, $h);

    //Here some fancy function is called
    if (method_exists($this,'img_'.$algorythm)){
        $this->{'img_'.$algorythm}($im,$w,$h);
    }

    header("Content-type: image/png");
    imagepng($im);
    imagedestroy($im);
}

Most of the times if the image is large enough the browser displays it just as expected, but if the image is to small laravel overwrites the content type header with "text/html; charset=UTF-8".

I've read https://laravel.com/docs/5.4/responses but to make it this way I need to have a string.

So I've looked at this: PHP: create image with ImagePng and convert with base64_encode in a single file? but I'm not sure if this is the right way, it looks like a dirty hack to me.

Should I put the imagepng call inside a view and add the headers there, isn't this a bit overkill?

How to use functions that output data instead of returning it in laravel.

shareimprove this questionedited May 23 '17 at 12:25Community♦11asked Feb 23 '17 at 16:15Falk306211


2 Answers 正确答案

Laravel controller actions are usually expected to give a response of some sort, which defaults to text/html.

Your fix could be as easy as: (好像在 laravel 控制器中不能这么用,好像只能在php这么用)

    header("Content-Type: image/png");
    imagepng($im);
    imagedestroy($im);
    exit;
}

Alternatively you can use a package like intervention (http://image.intervention.io). From which you can generate an image response.

shareimprove this answeredited Feb 23 '17 at 18:11answered Feb 23 '17 at 17:03Robert2,1231813

   You mean I just need to add exit at the end? – Falk Feb 23 '17 at 17:10   Yes, it will stop execution, so no more headers or other content will be added to the output and the image will just display as is. – Robert Feb 23 '17 at 18:08   Great it works! – Falk Feb 23 '17 at 22:01

One way would be to capture the image output with ob_get_contents and then make a response with that:

public function imga($algorythm,$w=false,$h=false){
    if (!$w) $w=rand(250,750);
    if (!$h) $h=rand(250,750);
    $im = imagecreatetruecolor($w, $h);

    //Here some fancy function is called
    if (method_exists($this,'img_'.$algorythm)){
        $this->{'img_'.$algorythm}($im,$w,$h);
    }


    ob_start();
    $rendered_buffer = imagepng($im);
    $buffer = ob_get_contents();
    imagedestroy($im);
    ob_end_clean();

    $response = Response::make($rendered_buffer);
    $response->header('Content-Type', 'image/png');
    return $response;
}

EDIT: Just saw your link, this is basically just an implementation of that.

If you want a "more laravel" way, you could save the image, return it, then delete it:

public function imga($algorythm,$w=false,$h=false){
    if (!$w) $w=rand(250,750);
    if (!$h) $h=rand(250,750);
    $im = imagecreatetruecolor($w, $h);

    //Here some fancy function is called
    if (method_exists($this,'img_'.$algorythm)){
        $this->{'img_'.$algorythm}($im,$w,$h);
    }

    // store the image
    $filepath = storage_path('tmpimg/' . uniqid() . '.png');
    imagepng($im, $filepath);
    imagedestroy($im);

    $headers = array(
        'Content-Type' => 'image/png'
    );

    // respond with the image then delete it
    return response()->file($filepath, $headers)->deleteFileAfterSend(true);
}
shareimprove this answeredited Feb 23 '17 at 18:53answered Feb 23 '17 at 18:44Samsquanch4,63563871

   Great, works fine! – Falk Feb 23 '17 at 22:06

Your Answer

来自  https://stackoverflow.com/questions/42420935/laravel-generate-image-and-add-content-type-header

普通分类: