Không thể trích xuất và đặt kích thước SVG


7

Cho đến nay, tôi không gặp vấn đề gì với hình thu nhỏ ảnh nền trong chủ đề của mình. Tuy nhiên, bây giờ khi tôi đang cố gắng sử dụng một SVG làm hình ảnh đặc trưng, ​​một cái gì đó đang phá vỡ. Vấn đề dường như liên quan đến chiều rộng của các SVG được trả về bằng 0 wp_get_attachment_image_src(). Vì vậy, những gì tôi đang cố gắng làm là tìm ra cách trích xuất thông tin chiều rộng và chiều cao từ SVG, sau đó đặt chúng thành các giá trị phù hợp trong các trường cơ sở dữ liệu của SVG, không dễ dàng.

Lưu ý: không có vấn đề chung khi tải lên hoặc hiển thị các Svss, chúng hiển thị tốt trong logo của tôi.

Lỗi và mã: bằng chứng về độ rộng bằng không

Đây là lỗi mà Wordpress ném trên trang: Warning: Division by zero in /wp-content/themes/tesseract/functions.php on line 771

Đây là mã trong hàm.php trước lỗi (trên dòng 771).

    /*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 ****/

Bạn có thể thấy có một bộ phận với $wrmẫu số. Dường như nó $wrđang được tính là 0 vì yếu tố duy nhất không phải là hằng số của $wnó cũng bằng không (yếu tố khác là 720, vì vậy không thể đổ lỗi). $wGiá trị được xác định bởi $thumbnail[1]. $thumbnail[1]Giá trị của được đặt trên dòng 763 với mã này:

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

Và theo Codex , giá trị thứ hai trong mảng trả về của hàm wp_get_attachment_image_src(nghĩa là $thumbnail[1]) thực sự là chiều rộng của hình thu nhỏ. Giá trị đó dường như bằng 0, bởi vì nó có cùng giá trị với $w, đó thực sự là mẫu số trên dòng 771. :(

Lưu ý quan trọng: Chủ đề của tôi triển khai hình thu nhỏ dưới dạng hình nền

Chủ đề gốc mà tôi đang sử dụng, "Tesseract", đặt các hình ảnh nổi bật làm hình nền của các neo / <a>phần tử, thay vì đặt chúng làm <img>các phần tử. Tôi không tin đây là nguyên nhân của vấn đề, nhưng khi đưa ra giải pháp, chúng phải tương thích với ảnh nền chứ không phải <img>đối tượng.

Không thể điều chỉnh sửa lỗi # 1:

Tôi đã tìm thấy trang web này cung cấp cách khắc phục các sự cố khi sử dụng SVG làm hình ảnh nổi bật. Nó cho thấy vấn đề có liên quan đến tính toán chiều rộng. Tuy nhiên, tôi không thể áp dụng sửa lỗi đó vì nó dành cho một imgphần tử có SVG là a src, tôi có một <a>phần tử có vị trí SVG được đặt thành background-image- url.

Đây là bản sửa lỗi

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');

Khắc phục lỗi số 2 (độ rộng tối thiểu qua CSS) không hoạt động

Dựa trên ý tưởng tôi có được từ trang trên, chiều rộng của vấn đề có thể là vấn đề, tôi đã thử đặt độ rộng tối thiểu 50% chỉ bằng CSS cho <a>. Đây là mã:

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

Các công cụ dành cho nhà phát triển của tôi cho thấy CSS "đã", ​​độ rộng tối thiểu được đặt thành 50%. Tuy nhiên, WP đã ném cùng một lỗi mà hình ảnh không hiển thị. Có lẽ CSS không thiết lập nó trước khi Hàm.php chạy wp_get_attachment_image_src, vì vậy nó không thành vấn đề?

Bất cứ ai cũng có bất kỳ manh mối nào về cách làm việc xung quanh tính toán bằng không này? Tôi thực sự muốn làm cho nó hoạt động với hình nền, và không phải ghi đè quá nhiều chủ đề gốc.

Khắc phục lỗi số 3 (nối bộ lọc) không hoạt động.

Với sự giúp đỡ của @Milo, @NathanJohnson và @prosti, tôi đã có thể thử một bộ lọc để thay đổi wp_get_attachment_image_src(). Mã không tạo ra lỗi nhưng nó không xóa lỗi phân chia hoặc hiển thị SVG. Đoạn mã này tôi đặt vào hàm.php. Có lẽ các ưu tiên là sai? :

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

Điểm mấu chốt:

Tôi tin rằng tôi cần tìm ra cách trích xuất thông tin chiều rộng từ chính tệp SVG và thêm nó vào cơ sở dữ liệu WP trước khi hàm.php chạy tính toán trên dòng 771. Nếu bạn biết cách, hướng dẫn của bạn sẽ thực sự được đánh giá cao.

Một số tài nguyên có thể hữu ích

  • Câu hỏi này dường như có thông tin hữu ích và đoạn trích được cung cấp bởi @Josh ở đó cho phép tôi cuối cùng xem các SVG của mình trong thư viện phương tiện, nhưng hình ảnh đặc trưng vẫn bị hỏng.
  • Câu hỏi này dường như có một số giải pháp dựa trên XML nhưng tôi không biết làm thế nào để thích ứng nó với WP.
  • Ngoài ra một bình luận dưới đây đã chỉ cho tôi bộ lọc này có vẻ phù hợp.

Tiêu đề của tệp SVG

Đây là tiêu đề 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">

1
Nhìn vào wp_get_attachment_image_srctrong mã nguồn, có một bộ lọc cùng tên. Sử dụng bộ lọc để trả về kích thước chính xác cho hình ảnh svg.
Milo

1
Các SVG không thực sự là "hình ảnh" và WordPress không có hỗ trợ riêng cho chúng. Bạn cần xem xét bất cứ điều gì đang thêm hỗ trợ SVG vào trang web của bạn và giải quyết vấn đề trong đó.
Otto

1
Nhìn vào fix_wp_get_attachment_image_svgchức năng ở đây và nơi bộ lọc được thêm vào đây . Đọc add_filtertrong tài liệu để giải thích về các bộ lọc.
Milo

1
Các SVG không phải là hình ảnh, vì vậy khi WordPress tính kích thước hình ảnh, nó không nhận ra tệp là hình ảnh, vì vậy nó trả về số không. Sử dụng bộ lọc wp_get_attachment_image_src để "thủ công" trả về kích thước của hình ảnh có vẻ như là cách tiếp cận chính xác.
Nathan Johnson

Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Howdy_McGee

Câu trả lời:


7

Tôi đã giải quyết nó !!! Bộ lọc trong bản sửa lỗi số 3 (ở trên) không hoạt động do điều kiện thứ ba của ifcâu lệnh này kích hoạt trích xuất và đính kèm kích thước:

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

$image[1]trong điều kiện thứ ba là chiều rộng được báo cáo của tệp SVG khi WP nhìn thấy nó trước khi vào bộ lọc. Vì tôi biết rằng giá trị của nó, chiều rộng là 0 (từ "lỗi phân chia không" được mô tả ở trên), tôi nghi ngờ rằng giá trị này cần phải được thay đổi để phù hợp với nó. Tôi đã thay đổi trận chung kết 1với ifđiều kiện đó thành 0a..voila! Lỗi phân chia biến mất và hình ảnh hiển thị, và tôi có thể quảng cáo rất đẹp!

Tôi đã có thể phát hiện ra điều này bởi vì trong nhiều diễn đàn, mọi người phàn nàn rằng các SVG không chính xác được gán độ rộng 1px. Đây có thể là trường hợp trong một số phiên bản của WP, nhưng trong thư viện phương tiện WP 4.7.2 của tôi, không có thứ nguyên nào cho SVG, thậm chí không 1pxđược đăng, như một thứ nguyên. Thay vào đó đơn giản là không có siêu dữ liệu về kích thước trong trường hợp của tôi.

Tôi nghĩ rằng một phiên bản linh hoạt của bộ lọc sẽ cho phép áp dụng nó nếu chiều rộng là 1 hoặc 0, đối với những người gặp sự cố 1px và đối với những người như tôi, người có chiều rộng bằng 0. Dưới đây tôi đã bao gồm sửa chữa, sử dụng $image[1] <= 1như điều kiện thứ ba của ifcâu lệnh thay vì $image[1] == 1nhưng tôi cho rằng bạn cũng có thể sử dụng điều này:( ($image[1] == 0) || ($image[1] == 1) )

Bộ lọc làm việc

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

Cảm ơn tất cả mọi người vì sự giúp đỡ của bạn, đó thực sự là một nỗ lực của nhóm!


Không hoạt động trên WordPress 4.9.4
Vadim H

2

Thật khó để đoán chính xác điều gì có thể là vấn đề đối với người đam mê WordPress như tôi nhưng vì bạn đã ping tôi trong Vòng lặp ...

Chỉ cần đề cập đến việc bạn chưa chia sẻ tệp chủ đề ...

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

Phần này với:

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

Có vẻ như vấn đề vì hình ảnh SVG không có thông tin kích thước . Họ chỉ phù hợp với container.

Vì vậy, bạn có thể tạo phiên bản của riêng mình wp_get_attachment_image_srcnơi bạn có thể đặt kích thước bằng cách nào đó.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.