Laravel 生成图片并添加内容类型标题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42420935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 15:24:18  来源:igfitidea点击:

Laravel generate image and add content type header

phplaravelheaderoutput

提问by Falk

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.

嗨,我正在使用 php 的 gd 库来生成图像。我决定将它集成到 Laravel 中,并且我设法让它工作。

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

我的问题是,如果 laravel 有时会覆盖我的内容类型标头。

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".

大多数情况下,如果图像足够大,浏览器会按预期显示它,但如果图像很小,laravel 会用“text/html; charset=UTF-8”覆盖内容类型标题。

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

我已经阅读了https://laravel.com/docs/5.4/responses但要做到这一点,我需要有一个字符串。

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.

所以我看了这个:PHP: create image with ImagePng and convert with base64_encode in a single file? 但我不确定这是否是正确的方法,对我来说这看起来像是一个肮脏的黑客。

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

我应该将 imagepng 调用放在视图中并在那里添加标题,这不是有点矫枉过正吗?

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

如何使用输出数据而不是在 laravel 中返​​回数据的函数。

回答by Robert

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

Laravel 控制器动作通常会给出某种响应,默认为text/html

Your fix could be as easy as:

您的修复可以很简单:

    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.

或者,您可以使用干预之类的包(http://image.intervention.io)。您可以从中生成图像响应。

回答by Samsquanch

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

一种方法是捕获图像输出,ob_get_contents然后用它做出响应:

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:

如果你想要一个“更多 laravel”的方式,你可以保存图像,返回它,然后删除它:

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);
}