LiipImagineBundle: Applying filter to a SVG file does not work

Hi there. I have a serious problem resizing SVG files… For example, I saved the same file as SVG and as PNG.

Code:

<img src="{{ '/uploads/file.png'|imagine_filter('thumbnail') }}" />
<img src="{{ '/uploads/file.svg'|imagine_filter('thumbnail') }}" />

Thumbnail shows only for the first image.

The error is: Unable to create image for path "uploads/file.svg" and filter "thumbnail". Message was "Unable to open image ~app/../web/uploads/file.svg" But the file exists in the filesystem!

Also, the generated path for this SVG file is incorrect: http://localhost:8000/media/cache/resolve/avatar_thumb/uploads/file.svg Why ‘resolve’?

Instead of: http://localhost:8000/media/cache/avatar_thumb/uploads/file.svg

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 4
  • Comments: 22 (10 by maintainers)

Most upvoted comments

This still happens with a relatively clean installation with gd driver on Symfony 5.0

if using imagick, try to install libmagickcore-6.q16-6-extra

looking at that stack trace, i am pretty sure hte problem is on imagine’s side. the call we use does not pass a mime type along, so its imagine not discovering svg correctly, i would say. please report the problem at the imagine library - for them it might be useful to have the svg data to be able to reproduce the bug.

I had a hard time to find a solution. It’s a little bit hacky but it works. In fact I create a custom twig filter to return the original image uploaded if the file has an svg extension. And I apply the filter after the imagine_filter. Not very clean. Thx for letting me know if you find a better option.

<?php
// AppBundle\Twig\TwigExtension
namespace AppBundle\Twig;

class TwigExtension extends \Twig_Extension
{    
    public function getFilters(){
        return array(
            new \Twig_SimpleFilter('svg', array($this, 'svgFilter')),
        );
    }

    public function svgFilter($liipFilepath){
	$ext = pathinfo($liipFilepath, PATHINFO_EXTENSION);
        $ext === "svg" ? $response = "yourOriginalDirectoryForYourImages/".basename($liipFilepath) : $response = $liipFilepath;
	return $response;
    }
}

and in a template, just do:

# template.html.twig
<img src="{{asset("yourOriginalDirectoryForYourImages/image.svg")|imagine_filter('yourFilter')|svg}}"/>

As I use a custom ImagineController I’ve solved it not applying the filter to svg images on filerAction:

$binary = $this->dataManager->find($filter, $path);
if ($binary->getFormat() === 'svg') {
    $filteredBinary = $binary;
} else {
    $filteredBinary = $this->filterManager->applyFilter($binary, $filter);
}

$this->cacheManager->store(
    $filteredBinary,
    $path,
    $filter,
    $resolver
);

Found out that the generated cache file is encoded as a Jpeg but has a .svg extension. Does that help?