使用过滤器提取SVG文件后,在该文件上设置媒体元数据(即“维度”字段

时间:2017-02-08 作者:CoderScissorhands

我的问题是如何将我从SVG中成功提取的尺寸标注附加到与文件关联的WP“dimensions”字段中,以便这些标注显示在媒体库中。

注:这是not 与…一样this earlier question I posted. 在这个问题中,我问了如何提取维度值。但是,没有人知道如何将该值永久设置为SVG,以便它显示在媒体库中

其中,我提取维度,我使用过滤器从SVG中提取图像维度。此过滤器允许我将SVG显示为特征图像,而不仅仅是徽标。我使用的过滤器从SVG文件内部识别SVG的大小,然后重置image[1]$image[2] 返回的数组中的值wp_get_attachment_image_src() 这就是功能:

File: wp-includes/media.php
804: /**
805:  * Retrieve an image to represent an attachment.
806:  *
807:  * A mime icon for files, thumbnail or intermediate size for images.
808:  *
809:  * The returned array contains four values: the URL of the attachment image src,
810:  * the width of the image file, the height of the image file, and a boolean
811:  * representing whether the returned array describes an intermediate (generated)
812:  * image size or the original, full-sized upload.
813:  *
814:  * @since 2.5.0
815:  *
816:  * @param int          $attachment_id Image attachment ID.
817:  * @param string|array $size          Optional. Image size. Accepts any valid image size, or an array of width
818:  *                                    and height values in pixels (in that order). Default \'thumbnail\'.
819:  * @param bool         $icon          Optional. Whether the image should be treated as an icon. Default false.
820:  * @return false|array Returns an array (url, width, height, is_intermediate), or false, if no image is available.
821:  */
822: function wp_get_attachment_image_src( $attachment_id, $size = \'thumbnail\', $icon = false ) {
823:    // get a thumbnail or intermediate image if there is one
824:    $image = image_downsize( $attachment_id, $size );
825:    if ( ! $image ) {
826:        $src = false;
827: 
828:        if ( $icon && $src = wp_mime_type_icon( $attachment_id ) ) {
829:            /** This filter is documented in wp-includes/post.php */
830:            $icon_dir = apply_filters( \'icon_dir\', ABSPATH . WPINC . \'/images/media\' );
831: 
832:            $src_file = $icon_dir . \'/\' . wp_basename( $src );
833:            @list( $width, $height ) = getimagesize( $src_file );
834:        }
835: 
836:        if ( $src && $width && $height ) {
837:            $image = array( $src, $width, $height );
838:        }
839:    }
这是我应用于该函数的过滤器,它更改$image[1]$image[2] (即图像宽度和高度)。

 add_filter( \'wp_get_attachment_image_src\', \'fix_wp_get_attachment_image_svg\', 10, 4 );  /* the hook */

 function fix_wp_get_attachment_image_svg($image, $attachment_id, $size, $icon) {
    if (is_array($image) && preg_match(\'/\\.svg$/i\', $image[0]) && $image[1] <= 1) {
        if(is_array($size)) {
            $image[1] = $size[0];
            $image[2] = $size[1];
        } elseif(($xml = simplexml_load_file($image[0])) !== false) {
            $attr = $xml->attributes();
            $viewbox = explode(\' \', $attr->viewBox);
            $image[1] = isset($attr->width) && preg_match(\'/\\d+/\', $attr->width, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[2] : null);
            $image[2] = isset($attr->height) && preg_match(\'/\\d+/\', $attr->height, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[3] : null);
        } else {
            $image[1] = $image[2] = null;
        }
    }
    return $image;
} 
过滤器工作,但媒体库不显示提取的数据过滤器工作$image[1]$image[2] 正在分配给放置的SVG元素的html宽度和高度。但是,正如下图所示,过滤器似乎没有更新图像的dimensions WP数据库中的字段。

library view of SVG vs PNG

我的问题总结:

我如何获取过滤器检索到的这些维度值,并将它们以允许我查看媒体库中维度的方式附加到数据库本身的图像文件?

谢谢

1 个回复
最合适的回答,由SO网友:Laxmana 整理而成

这个wp_update_attachment_metadata 每次通过媒体库上载图像时(特别是每次wp_update_attachment_metadata 正在调用函数)。

因此,上载svg文件时,我们会检查文件是否具有所需的元数据、宽度和高度。如果没有,我们将像您在wp_get_attachment_image_src 滤器现在元数据已经保存,我们可以调用如下函数wp_get_attachment_image_src 无需过滤这些函数即可获得metada。

注意以下问题:uploading svg files 在最新的Wordpress版本(4.7.2)中。应在4.7.3中固定

最后,我想提醒您svg文件暴露的潜在安全风险(XSS攻击)。更多herehere.

function svg_meta_data($data, $id){

    $attachment = get_post($id); // Filter makes sure that the post is an attachment
    $mime_type = $attachment->post_mime_type; // The attachment mime_type

    //If the attachment is an svg

    if($mime_type == \'image/svg+xml\'){

        //If the svg metadata are empty or the width is empty or the height is empty
        //then get the attributes from xml.

        if(empty($data) || empty($data[\'width\']) || empty($data[\'height\'])){

            $xml = simplexml_load_file(wp_get_attachment_url($id));
            $attr = $xml->attributes();
            $viewbox = explode(\' \', $attr->viewBox);
            $data[\'width\'] = isset($attr->width) && preg_match(\'/\\d+/\', $attr->width, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[2] : null);
            $data[\'height\'] = isset($attr->height) && preg_match(\'/\\d+/\', $attr->height, $value) ? (int) $value[0] : (count($viewbox) == 4 ? (int) $viewbox[3] : null);
        }

    }

    return $data;

}

add_filter(\'wp_update_attachment_metadata\', \'svg_meta_data\', 10, 2);

相关推荐

启用CORS以通过URL获取内联SVG

太长,读不下去了有没有办法在我的WordPress后端为SVG启用CORS,这样我就可以通过http请求将它们发送到其他域?理想情况下无需触摸.htaccess?我的目标是建立一个无头WordPress/React网站。我想让我的SVG上传到WP后端,内联到我的前端代码中(这样我就可以访问它们的DOM)。我有SVG的URL,并且react-inlinesvg 库允许我内联它。我正在No \'Access-Control-Allow-Origin\' header is present on the req