Skip to content
This repository has been archived by the owner on Dec 9, 2023. It is now read-only.

images not showing on laravel 5.4 #80

Open
BartHuis opened this issue Mar 28, 2017 · 37 comments
Open

images not showing on laravel 5.4 #80

BartHuis opened this issue Mar 28, 2017 · 37 comments

Comments

@BartHuis
Copy link

BartHuis commented Mar 28, 2017

Hi,
Just installed intervention/image and intervention/imagecache on laravel 5.4
I couldn't get the package working right. Tracked down the way how the image should be displayed all down to the ImageCacheController.
Requesting the original route The current output it returns is:

<html><head><meta name="viewport" content="width=device-width, minimum-scale=0.1"></head><body style="margin: 0px; background: rgb(14, 14, 14);"><img style="-webkit-user-select: none;background-position: 0px 0px, 10px 10px;background-size: 20px 20px;background-color: white;background-image:linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%),linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%);" src="http://domain.ext/img/original/image.jpg"></body></html>

and it's not showing any picture, only a square on a black screen:
squareinblack.png

when i change the getOriginal function to:

/**
     * Get HTTP response of original image file
     *
     * @param  string $filename
     * @return Illuminate\Http\Response
     */
    public function getOriginal($filename)
    {
        $path = $this->getImagePath($filename);

        //return $this->buildResponse();
    
        $imageData = base64_encode(file_get_contents($path));

        // Format the image SRC:  data:{mime};base64,{data};
        $src = 'data: '.mime_content_type($path).';base64,'.$imageData;

        // Echo out a sample image
        return '<img src="' . $src . '">';
    }

and requesting the original route, the output is:

<html><head></head><body><img src="data: image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAQECAQEBAgICAgICAgICA............etc................."></body></html>

and it's just working

I think something is wrong with the buildResponse function?

requesting other pre defined templates like small, medium and large are giving the same square as result.

Bart

@ghost
Copy link

ghost commented Apr 4, 2017

Hi,

I have the same issue on Laravel 5.1.31 and PHP 5.5.38.

Bart, have you fixed it?

Thanks.

@codemonkeynorth
Copy link

try this for instance (different for your example but.....) spent last 2 hours trying to find a fix and this did it!

ob_end_clean();
return($cachedImage->response('jpg'));
```php

from: 
http://simpledeveloper.com/how-to-fix-laravel-response-image-download-in-laravel/
https://laravel.io/forum/02-16-2016-laravel-51-intervention-corrupted-image

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

maybe @olivervogel can look at this, because it seems to be a package problem and not a usage problem?

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

thnx @codemonkeynorth seems to work when i add ob_end_clean(); at 2 places, so @zaplachinsky and people at issue #60 try to change the ImageCacheController.php to this: (of cource this is not THE solution, would be nice if @olivervogel will still look into the real problem)

<?php

namespace Intervention\Image;

use Closure;
use Intervention\Image\ImageManager;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Response as IlluminateResponse;
use Config;

class ImageCacheController extends BaseController
{
    /**
     * Get HTTP response of either original image file or
     * template applied file.
     *
     * @param  string $template
     * @param  string $filename
     * @return Illuminate\Http\Response
     */
    public function getResponse($template, $filename)
    {
        switch (strtolower($template)) {
            case 'original':
                return $this->getOriginal($filename);

            case 'download':
                return $this->getDownload($filename);
            
            default:
                return $this->getImage($template, $filename);
        }
    }

    /**
     * Get HTTP response of template applied image file
     *
     * @param  string $template
     * @param  string $filename
     * @return Illuminate\Http\Response
     */
    public function getImage($template, $filename)
    {
        $template = $this->getTemplate($template);
        $path = $this->getImagePath($filename);

        // image manipulation based on callback
        $manager = new ImageManager(Config::get('image'));
        $content = $manager->cache(function ($image) use ($template, $path) {

            if ($template instanceof Closure) {
                // build from closure callback template
                $template($image->make($path));
            } else {
                // build from filter template
                $image->make($path)->filter($template);
            }
            
        }, config('imagecache.lifetime'));
    
        ob_end_clean();
        return $this->buildResponse($content);
    }

    /**
     * Get HTTP response of original image file
     *
     * @param  string $filename
     * @return Illuminate\Http\Response
     */
    public function getOriginal($filename)
    {
        $path = $this->getImagePath($filename);
        ob_end_clean();
        return $this->buildResponse(file_get_contents($path));
    }

    /**
     * Get HTTP response of original image as download
     *
     * @param  string $filename
     * @return Illuminate\Http\Response
     */
    public function getDownload($filename)
    {
        $response = $this->getOriginal($filename);

        return $response->header(
            'Content-Disposition',
            'attachment; filename=' . $filename
        );
    }

    /**
     * Returns corresponding template object from given template name
     *
     * @param  string $template
     * @return mixed
     */
    private function getTemplate($template)
    {
        $template = config("imagecache.templates.{$template}");

        switch (true) {
            // closure template found
            case is_callable($template):
                return $template;

            // filter template found
            case class_exists($template):
                return new $template;
            
            default:
                // template not found
                abort(404);
                break;
        }
    }

    /**
     * Returns full image path from given filename
     *
     * @param  string $filename
     * @return string
     */
    private function getImagePath($filename)
    {
        // find file
        foreach (config('imagecache.paths') as $path) {
            // don't allow '..' in filenames
            $image_path = $path.'/'.str_replace('..', '', $filename);
            if (file_exists($image_path) && is_file($image_path)) {
                // file found
                return $image_path;
            }
        }

        // file not found
        abort(404);
    }

    /**
     * Builds HTTP response from given image data
     *
     * @param  string $content 
     * @return Illuminate\Http\Response
     */
    private function buildResponse($content)
    {
        // define mime type
        $mime = finfo_buffer(finfo_open(FILEINFO_MIME_TYPE), $content);

        // return http response
        return new IlluminateResponse($content, 200, array(
            'Content-Type' => $mime,
            'Cache-Control' => 'max-age='.(config('imagecache.lifetime')*60).', public',
            'Etag' => md5($content)
        ));
    }
}

@olivervogel
Copy link
Member

olivervogel commented Apr 5, 2017

What is the actual output on the requested image route? (Broken image or square on a black screen could be anything.)

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

@olivervogel thanks for the quick folowup ;)

<html><head><meta name="viewport" content="width=device-width, minimum-scale=0.1"></head><body style="margin: 0px; background: rgb(14, 14, 14);"><img style="-webkit-user-select: none;background-position: 0px 0px, 10px 10px;background-size: 20px 20px;background-color: white;background-image:linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%),linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%);" src="http://domain.ext/img/original/image.jpg"></body></html>

@olivervogel
Copy link
Member

No, I mean what do you get if you request only the image?

http://domain.ext/img/original/image.jpg

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

here i can also see the one string is working, the other not: http://freeonlinetools24.com/base64-image

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

@olivervogel when you're saved the base64 codes, please tell me, i'll delete it then, just to prevent others from tracking things we do ;)

@olivervogel
Copy link
Member

Why do you get base64 encoded data from the route? If you setup URL based image manipulation you should just get regular image data.

PS: You can delete.

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

deleted

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

no, i just get the image, but if i click the source in chrome, i get the base64, what other response would you like me to post? ;)

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

@olivervogel if you would like to, you can look with me at teamviewer? cant realy post all real routes and everything becouse of bussiness use ;)

@ghost
Copy link

ghost commented Apr 5, 2017

@olivervogel, I always get this square image when I request something like this:

http://domain.ext/img/original/image.jpg

fireshot capture 156 - - http___dev mousegame ru_i_original_uploads_2016_12_07_a364c7135214d277f

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

@zaplachinsky that's the same problem here ;)

@olivervogel
Copy link
Member

I think you setup imagecache like it is described in the docs. I would just like to know what image data you get from the route, when you got a corrupt image (square on black screen).

Just do a quick curl and take a look what you get:

$ curl -r 0-99 http://domain.ext/img/original/image.jpg

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

when its in the working and not working modus, i both get a screen with code but after a milisecond it clears and gives me:

          ▒@1▒▒▒

Bart@machine location
$ 1;2c^C

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

so nothing to see here

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

so chrome is just showing the right image when ob end clean in added, and the little square when not added. only when going into the chrome inspector and clicking on the sources tab, and clicking the image, is giving the base64 data, the working one and the not working one. any other inspector tab you want me to look at and copy paste to you? or wanna look with me?

@BartHuis
Copy link
Author

BartHuis commented Apr 5, 2017

@olivervogel and yes "I think you setup imagecache like it is described in the docs." yes i did it just folowing the docs ;)

@codemonkeynorth
Copy link

does this show anything useful?.. without, and then with ob_end_clean();

note the whitespace at the beginning

without
img-no-obclean

with
img-with-obclean

@BartHuis
Copy link
Author

BartHuis commented Apr 6, 2017

@codemonkeynorth yes, the base64 version that @olivervogel has now, was also different

@BartHuis
Copy link
Author

BartHuis commented Apr 6, 2017

my working and not working give different base64, but the same response as you, but instead of spaces in the beginning, i get a blank line at the wrong file, and no blank line at the right file.


ÿØÿà�JFIF���``ÿþ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90
ÿÛC���������������������
����
�
��

@BartHuis
Copy link
Author

BartHuis commented Apr 6, 2017

@codemonkeynorth what cache meganism is your default? here it's redis.
config/cache.php:

    'default' => env('CACHE_DRIVER', 'file'),

.env:

CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_DRIVER=redis

.env overrides the config

but, also when changing to CACHE_DRIVER=file, php restart, clear cache, it has the same behaviour.

what cache do you use @olivervogel ?

@codemonkeynorth
Copy link

I'm using file cache.

@olivervogel
Copy link
Member

The whitespace is the problem. But neither Intervention Image or Intervention Imagecache produces this whitespace. I think this may be a issue with Laravel's or Symfony's Cache/HTTP modules or the combination of them.

This might be helpful:
http://simpledeveloper.com/how-to-fix-laravel-response-image-download-in-laravel/

@BartHuis
Copy link
Author

BartHuis commented Apr 6, 2017

@olivervogel that's the same we do now, adding the ob_end_clean() before the return... so is that realy the solution? and should be added to your package? where is the output buffer start then? as i read the topic, it is somewhere in laravel itself, but the laravel code dousn't close it?

@codemonkeynorth
Copy link

codemonkeynorth commented Apr 6, 2017

hi @olivervogel . that's the link I posted above, which is where i got ob_end_clean() from

so I understand that it's a general Laravel buffer issue not a specific Intervention issue ,

thanks.

@olivervogel
Copy link
Member

Adding ob_end_clean to Intervention Imagecache seems like a fix/hack for a bug in another package. I think the problem should be fixed properly, where it is caused.

@BartHuis
Copy link
Author

BartHuis commented Apr 6, 2017

@olivervogel i'll ask laravel and point them to this ;)

@BartHuis
Copy link
Author

BartHuis commented Apr 6, 2017

@olivervogel @codemonkeynorth as you see, i posted an issue at the laravel framework: laravel/framework#18687 hope @themsaid or @taylorotwell will take a quick look at it ;)

@anilvpsmarterhomes
Copy link

ob_end_clean(); +1
before response->make()

@ArthurYdalgo
Copy link

try this for instance (different for your example but.....) spent last 2 hours trying to find a fix and this did it!

ob_end_clean();
return($cachedImage->response('jpg'));
```php

from: 
http://simpledeveloper.com/how-to-fix-laravel-response-image-download-in-laravel/
https://laravel.io/forum/02-16-2016-laravel-51-intervention-corrupted-image

Buddy... you just saved my day

Working in Laravel 7.4

$image = Image::make($user->avatar);
            
ob_end_clean();

return $image->response();

@sepisoltani
Copy link

ob_end_clean();
worked for me !

@dasundev
Copy link

dasundev commented Oct 22, 2020

ob_end_clean(); Is the solution :)

@ciceroborges
Copy link

ob_end_clean(); Is the solution 2 :)

@rayronvictor
Copy link

"Found a space before the php tag in my package's config file"

laravel/framework#18687 (comment)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants