laravel 无法从文件.SVG中读取图像(干预/图像)

qf9go6mv  于 2022-12-01  发布在  其他
关注(0)|答案(2)|浏览(188)

所以我做了一个图像上传器,我想在那里制作缩略图,但也支持svg,因为GD不支持svg类型,我第一次尝试切换到imagick在config/image.php文件,但没有改变什么。
我不确定,因为它确实声明它支持它,我是不是缺少了一个必须安装的软件包?如果是,是哪一个?。
但话虽如此,当我试图上传一张svg图片时,它会说:

NotReadableException in Decoder.php line 20:
Unable to read image from file (D:\xampp\htdocs\laravel\public\up/2017/01/07000323-logoSep.svg).

我首先尝试用一个简单的IF结构来解决这个问题,因为我并不真的需要SVG图像的缩略图,通过使用-〉mime(),但它只是说图像也不能打开/读取。

$image = $request->file('file');
$imageName = date("dHis-").$image->getClientOriginalName();
$uploadPath = public_path('up/').date("Y/m");
$image->move($uploadPath,$imageName);
$imageMime = Image::make($uploadPath.'/'.$imageName);
if($imageMime->mime() != "image/svg+xml"){}

我首先认为这是由权限问题引起的,所以我确保我所有的文件都是可读和可写的,但这并没有改变这个问题。
因此我尝试基于实际的扩展而不是mime类型,mime类型在我的情况下确实有些工作,如下所示:

public function dropzoneStore(Request $request){
    $image = $request->file('file');
    $imageName = date("dHis-").$image->getClientOriginalName();
    $uploadPath = public_path('up/').date("Y/m");
    $image->move($uploadPath,$imageName);
    if($image->getClientOriginalExtension() != 'svg'){
        $imageThmb = Image::make($uploadPath.'/'.$imageName);
        $imageThmb->fit(300,300,function($constraint){$constraint->upsize();})->save($uploadPath.'/thm_'.$imageName,80);
    }
    return response()->json(['success'=>$imageName]);
}

但是我发现这是一个相当笨拙的方法,难道没有更好的方法来过滤掉或支持整个干预/图像包中的svg类型吗?
提前感谢您提供更多信息!

n6lpvg4x

n6lpvg4x1#

因此,通过进一步的实验,并试图得到一些工作与停留在干预/图像库,但没有转换svg到任何东西,我已经与以下解决方案:

public function dropzoneStore(Request $request){
    $image = $request->file('file');
    $imageName = date("dHis-").preg_replace("/[^a-zA-Z0-9.]/","",$image->getClientOriginalName());
    $uploadPath = public_path('up/').date("Y/m");
    $image->move($uploadPath,$imageName);
    //Thumbnail Creation
    $thumbPath = $uploadPath.'/thumbs/';
    File::isDirectory($thumbPath) or File::makeDirectory($thumbPath,0775,true,true);
    if($image->getClientOriginalExtension() != 'svg'){
        $imageThmb = Image::make($uploadPath.'/'.$imageName);
        $imageThmb->fit(300,300,function($constraint){$constraint->upsize();})->save($uploadPath.'/thumbs/thm_'.$imageName,80);
    }else{
        File::copy($uploadPath.'/'.$imageName,$uploadPath.'/thumbs/thm_'.$imageName);
    }
    return response()->json(['success'=>$imageName]);
}

这虽然有点牵强和黑客的方法在我看来,仍然似乎做的伎俩,以配合我的文件系统,需要一个拇指为每一个图像。
当我进一步扩展我的网站的使用,最终将SVG图像转换为缩略图时,我可能会研究它。但现在这样做就可以了,因为.svg还没有被用于网站开发,我可以在负载方面也很轻松。
无论哪种方式,我感谢每一个试图帮助我处理这件事的人!

iezvtpos

iezvtpos2#

对于任何想要强制Intervention Image忽略SVG的人,我提出了一个非常好的解决方案(特定于Laravel,但也应该可以用于其他实现)。我在https://stevenwoodson.com/blog/making-intervention-image-ignore-svgs/中记录了它,但要点是app/Exceptions/Handler.php文件中的render方法增加了以下内容:

/**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Throwable   $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Throwable $exception)
    {
        /**
         * If the error class is `Intervention\Image\Exception\NotReadableException`, 
         * redirect the image URL to the original instead to avoid 500 errors on
         * the frontend. In particular, it has trouble with SVG images as the GD 
         * Library doesn't support anything other than JPG, PNG, GIF, BMP or WebP files.
         * 
         * This RegEx handles all Intervention Image filters defined ('/small/',
         * '/medium/', '/large/', for example) by isolating the URL path after
         * the configured Intervention URL Manipulation route (`imagecache` in 
         * this case) and replaces it with `/original/` which is a built in 
         * Intervention route that sends am HTTP response with the original image file.
         * 
         * @see https://image.intervention.io/v2/usage/url-manipulation
         */
        if ( get_class($exception) == "Intervention\Image\Exception\NotReadableException" ) {
            header('Location: '. preg_replace('/(imagecache\/[^\/]*\/)+/i', 'imagecache/original/', $request->getUri()) );
            exit();
        }

        return parent::render($request, $exception);
    }

这是什么做的整个描述是在注解块,一定要改变imagecache在那里,以任何您定义为您的路线在config/imagecache.php

相关问题