如何在WordPress中处理SVG渲染?

时间:2014-08-11 作者:gdaniel

随着互联网浏览器的发展,我发现自己在编写网站代码时越来越习惯使用SVG。。。特别是图标和简单的图形,可以用PNG即时替换。

看起来wordpress几乎支持SVG。我这么说几乎是因为:

默认情况下,它不是wordpress中允许的文件类型。所以你需要在上传SVG之前添加它

在媒体库中看不到SVG缩略图。(见下图)

有时,当您将svg添加到编辑器(通过添加媒体按钮)时,编辑器不知道svg的大小,因此尽管它将svg添加为图像,但其宽度和高度为零。

当您在媒体上传弹出窗口中单击“编辑图像”时,您会收到一条消息,说“图像不存在”。请参见下图。

我对列表中的项目1很满意,但有人知道如何修复项目2、3和4吗?

enter image description hereenter image description here

Update about item 1:

要允许新的mime类型(如SVG),只需在函数中添加一个挂钩即可。php

function allow_new_mime_type($mimes) {

    $mimes[\'svg\'] = \'image/svg+xml\';

    return $mimes;
}
add_filter( \'mime_types\', \'allow_new_mime_type\' );
现在您应该可以上传SVG了。您可以在中找到更多信息this tutorial. 这只解决了第1项,正如我前面提到的,这对我来说不是问题(尽管我认为默认情况下应该是允许的)。

Update about item 2:

我做了一些挖掘,并找到了决定附件是否是图像的函数。似乎这一切都归结为wp includes/post中的此功能。php

/**
 * Check if the attachment is an image.
 *
 * @since 2.1.0
 *
 * @param int $post_id Attachment ID
 * @return bool
 */
function wp_attachment_is_image( $post_id = 0 ) {
    $post_id = (int) $post_id;
    if ( !$post = get_post( $post_id ) )
        return false;

    if ( !$file = get_attached_file( $post->ID ) )
        return false;

    $ext = preg_match(\'/\\.([^.]+)$/\', $file, $matches) ? strtolower($matches[1]) : false;

    $image_exts = array( \'jpg\', \'jpeg\', \'jpe\', \'gif\', \'png\' );

    if ( \'image/\' == substr($post->post_mime_type, 0, 6) || $ext && \'import\' == $post->post_mime_type && in_array($ext, $image_exts) )
        return true;
    return false;
}
正如您所看到的,在这个函数中定义了一系列有效的图像扩展。我没有看到任何可以用来修改该数组的过滤器。但这只是一个开始。。。

但我不知道为什么SVG的最后一个if语句返回false。即使我没有将svg扩展添加到数组$image\\u exts中,第一个条件也应该返回true,不是吗?

if ( \'image/\' == substr($post->post_mime_type, 0, 6)
检查“image/”是否与mime类型中的前六个字符相等,对于svg,它是image/svg+xml(前六个是“image/”)。

UPDATE

经进一步调查,问题似乎根本不在于wp\\U attachment\\U is\\u image,而是因为在上载SVG时,没有将图像大小(宽度和高度)添加到附件元数据中。这是因为用于计算所用图像的函数是php函数getimagesize(),它不会为SVG返回图像大小。我在stackoverflow上找到了关于getimagesize函数和SVG行为的答案。See it here.

3 个回复
SO网友:Josh

看看wp_prepare_attachment_for_js(), 它收集附件元数据以在媒体页面上使用。同名过滤器允许我们添加或更改元数据。

以下示例可以放入函数中。php。注意:这需要PHP中的SimpleXML支持。

function common_svg_media_thumbnails($response, $attachment, $meta){
    if($response[\'type\'] === \'image\' && $response[\'subtype\'] === \'svg+xml\' && class_exists(\'SimpleXMLElement\'))
    {
        try {
            $path = get_attached_file($attachment->ID);
            if(@file_exists($path))
            {
                $svg = new SimpleXMLElement(@file_get_contents($path));
                $src = $response[\'url\'];
                $width = (int) $svg[\'width\'];
                $height = (int) $svg[\'height\'];

                //media gallery
                $response[\'image\'] = compact( \'src\', \'width\', \'height\' );
                $response[\'thumb\'] = compact( \'src\', \'width\', \'height\' );

                //media single
                $response[\'sizes\'][\'full\'] = array(
                    \'height\'        => $height,
                    \'width\'         => $width,
                    \'url\'           => $src,
                    \'orientation\'   => $height > $width ? \'portrait\' : \'landscape\',
                );
            }
        }
        catch(Exception $e){}
    }

    return $response;
}
add_filter(\'wp_prepare_attachment_for_js\', \'common_svg_media_thumbnails\', 10, 3);

SO网友:Otto

这并不是你能够轻易地用插件或一些小代码集“入侵”的东西。

其不足之处在于,SVG总的来说,并不是之前所有图像的意义上的“图像”。SVG是基于矢量的图像,是第一个在网络上获得真正吸引力的图像。

之前的所有图像都是基于位图的。WordPress的图像处理系统是专门为处理这些问题而编写的,这种固有的设计位于系统中的每一点。

例如,这是一个基本假设,即图像具有宽度和高度。SVG两者都没有,它们可以是任何大小。WordPress中有一个完整的图像基本“编辑器”,其中没有一个功能可以真正应用于SVG。

多媒体系统正在慢慢地重新开发,这里的重点是“慢慢地”。有大量的向后兼容性需要维护,新的设计需要实施。此外,大多数人对支持视频、音频和播放列表更感兴趣。随着重新设计工作的完成,库的各个部分变得更加抽象,随着时间的推移,这类事情将变得更容易支持。但它还没有出现,而且暂时不会出现。这就是为什么不支持SVG mime类型,因为在所有底层工作之前添加该mime类型将是一条破坏之路。

对于SVGwp_attachment_is_image 应返回false,因为wp_attachment_is_image 用于确定是否显示编辑器按钮以及是否显示image_downsize 尝试将图像调整为缩略图等。无论如何,这两种方法都不适用于SVG。要正确支持SVG,您需要编写一个新的系统来为这些图像添加完整的元数据,然后在可能使用元数据的所有位置添加对它的支持。正如你所想象的,这不是一个小工作。

SO网友:kaiser

仅通过阅读源代码(而非测试),我就可以看到扩展需要匹配:

if ( \'image/\' == substr($post->post_mime_type, 0, 6) || $ext && \'import\' == $post->post_mime_type && in_array($ext, $image_exts) )
读作(伪代码)

如果image/ 是$post object post\\U mime\\U type属性中的前6个字符,或者存在扩展或import 是$post objects post\\U mime\\U type属性,当前文件扩展名是(数组)之一

这意味着最后一句话将始终决定if 不管结果是真是假。

从我能读到的get_attached_file(), 有一个允许伪造扩展名的过滤器:

return apply_filters( \'get_attached_file\', $file, $attachment_id );
换句话说,您可以尝试返回相同的文件,但扩展名不同。它不会与其他部分冲突,因为wp_attachment_is_image() 仅返回bool.

结束

相关推荐

如何使用媒体上传器上传SVG图像?

我真的很喜欢使用SVG图像,因为我可以将它们缩放到我想要的大小。然而,WordPress不允许我使用媒体上传器上传它们。我怎样才能改变这个?