web-dev-qa-db-ja.com

SVG寸法を抽出および設定できません

今までのところ、私はテーマの背景画像のサムネイルに問題はありませんでした。しかし、SVGを特集画像として使用しようとしている今、何かが壊れています。問題はSVGの幅がwp_get_attachment_image_src()によってゼロとして返されることに関連しているようです。ですから、私がやろうとしているのは、SVGから幅と高さの情報を抽出し、それをSVGデータベースのフィールドで適切な値に設定する方法を理解することです。

注:svgsのアップロードやレンダリングに一般的な問題はありません。私のロゴではうまく表示されます。

エラーとコード:ゼロ幅の証拠

これはWordpressがページに投げるエラーです:Warning: Division by zero in /wp-content/themes/tesseract/functions.php on line 771

これは(771行目で)エラーが発生する前のfunctions.phpのコードです。

    /*759*/ function tesseract_output_featimg_blog() {
    /*760*/
    /*761*/ global $post;
    /*762*/
    /*763*/ $thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );
    /*764*/ $featImg_display = get_theme_mod('tesseract_blog_display_featimg');
    /*765*/ $featImg_pos = get_theme_mod('tesseract_blog_featimg_pos');
    /*766*/
    /*767*/ $w = $thumbnail[1]; /* supposed to return thumbnail width */
    /*768*/ $h = $thumbnail[2];  /* supposed to return thumbnail height */
    /*769*/ $bw = 720;
    /*770*/ $wr = $w/$bw;  
    /*771*/ $hr = $h/$wr; /**** this is the line that throws the error ****/

分母として$wrを使った除算があることがわかります。その唯一の非定数係数$wrもゼロであるため、$wはゼロとして計算されているようです(他の係数は720であるため、非難することはできません)。 $wの値は$thumbnail[1]によって決定されます。 $thumbnail[1]の値は、次のコードで行763に設定されています。

$thumbnail = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' );

そして the Codex によると、関数wp_get_attachment_image_srcの戻り値の配列の2番目の値(つまり$thumbnail[1])は、実際にはサムネイルの幅です。その値はゼロであるように見えます。なぜなら、それは$wと同じ値であり、それは771行目で実際には分母であるからです。

重要な注意:私のテーマは背景画像としてサムネイルを実装しています

私が使っている親テーマ "Tesseract"では、注目の画像を<a>要素として配置するのではなく、アンカー/ <img>要素の背景画像として配置しています。 これが問題の原因ではないと思いますが、ソリューションを提供するときは、<img>オブジェクトではなくbackground-imagesと互換性があるべきです。

修正#1を適用できませんでした。

このWebページ は、SVGをフィーチャーイメージとして使用する際の問題に対する修正を提供します。それは問題が幅の計算に関連していることを示唆しています。ただし、SVGをimgとして持つsrc要素を対象としているため、この修正を適用することはできません。SVGの場所を<a>-urlに設定したbackground-image要素があります。

これは修正です

function custom_admin_head() {
  $css = '';
  $css = 'td.media-icon img[src$=".svg"] { width: 100% !important; height: auto !important; }';
  echo '<style type="text/css">'.$css.'</style>';
}
add_action('admin_head', 'custom_admin_head');

#2の修正(CSSによる最小幅)が機能しなかった

上のページから得たアイデアに基づいて、の幅が問題になるかもしれないということに基づいて、私はCSSだけを使用して最小幅を50%に設定することを試みました<a>。これがコードです:

a.entry-post-thumbnail.above {
    min-width: 50% !important;
} 

私の開発者ツールは、CSSが「採用」し、最小幅が50%に設定されることを示しました。それでもWPは画像が表示されなかったのと同じエラーを投げました。 functions.phpがwp_get_attachment_image_srcを実行する前にCSSが設定していないのかもしれませんが、問題ありませんか。

誰もがこのゼロ計算を回避する方法について何か手がかりをお持ちですか?私は本当にこれを背景画像で、そしてあまりにも多くの親テーマを上書きする必要なしに機能させたいです。

修正#3(フィルタをフックする)がうまくいかなかった。

@Milo、@ NathanJohnson、および@prostiの助けを借りて、私はwp_get_attachment_image_src()を変更するためのフィルタを試すことができました。このコードではエラーは発生しませんが、除算エラーが除去されたりSVGに表示されることはありません。これは私がfunctions.phpに入れたスニペットです。おそらく優先順位が間違っている? :

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;
    } 

一番下の行:

Functions.phpが771行目で計算を実行する前に、SVGファイル自体から幅の情報を抽出してWPデータベースに追加する方法を理解する必要があると思います。本当に感謝します。

役に立つ可能性のあるリソース

  • この質問 は有益な情報を持っているようです、そしてそこに@Joshによって提供されたスニペットは私がメディアライブラリで私のSVGをついに見ることを可能にしました、しかし特集画像はまだ壊れています。
  • この質問 にはXMLベースの解決策がいくつかあるようですが、それをWPに適応させる方法がわかりません。
  • また、以下のコメント投稿者の1人は、 このフィルター に関連性があるようです。

SVGファイルのヘッダ

これはSVGヘッダです:

<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="475.419px" height="406.005px" viewBox="0 0 475.419 406.005" enable-background="new 0 0 475.419 406.005" xml:space="preserve">
7

私はそれを解決しました!上記の修正#3のフィルタは、ディメンションの抽出と添付をトリガするこのifステートメントの3番目の条件のために機能しませんでした。

if (is_array($image) && preg_match('/\.svg$/i', $image[0]) && $image[1] == 1)

3番目の条件の$image[1]は、WPがフィルタに入る前に表示されるSVGファイルの報告された幅です。その値、幅が0であることがわかっているので(上記の「ゼロ除算エラー」から)、この値をそれに合わせるために変更する必要があると私は疑った。そのif条件の最後の10に変更しました。分割エラーがなくなり、画像が表示されています。美しく表示されますので、お勧めします。

多くのフォーラムでSVGが1pxの割り当て幅を誤って取得していると不満を言う人がいたので、これを見つけることができました。これはおそらくWPのいくつかのバージョンの場合でしたが、私のWP 4.7.2メディアライブラリでは、SVGのディメンションはなく、1pxさえディメンションとして投稿されていません。代わりに、私の場合は単にディメンションに関するメタデータはありませんでした。

柔軟なバージョンのフィルタは、1pxの問題を抱えている人や幅が0の私のような人には幅が1または0の場合に適用できると思います。以下に$image[1] <= 1asを使った修正を含めました。 $image[1] == 1ではなくifステートメントの3番目の条件ですが、これも使用できると思います。( ($image[1] == 0) || ($image[1] == 1) )

作業フィルター

 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;
} 

本当にチームの努力だったあなたの助けをみんなありがとう!

6

私のようなWordPress愛好家のために何が問題になる可能性があるのか​​正確に推測するのは難しいですが、あなたは私をLoopにピン留めしたので...

あなたがテーマファイルを共有していないことを言及するだけで...

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:    }

この部分と:

@list( $width, $height ) = getimagesize( $src_file );

SVG画像からの問題のように見えます サイズ情報を持っていません 。彼らはちょうど容器に収まります。

それで、あなたは何とかサイズを設定することができるwp_get_attachment_image_srcのあなた自身のバージョンを作成することができます。

2
prosti