Cách xử lý kết xuất SVG trong wordpress?


9

Với sự tiến bộ của trình duyệt internet, tôi thấy mình ngày càng thoải mái hơn khi sử dụng SVGS khi mã hóa trang web ... đặc biệt là các biểu tượng và đồ họa đơn giản có thể được thay thế nhanh chóng bằng pngs.

Có vẻ như wordpress gần như hỗ trợ SVGS. Tôi nói gần như bởi vì:

  1. Theo mặc định, đây không phải là loại tệp được phép trong wordpress. Vì vậy, bạn cần thêm nó trước khi tải lên SVG

  2. Bạn không thể thấy hình thu nhỏ của SVG trong thư viện Media. (xem hình dưới đây)

  3. Đôi khi, khi bạn thêm nó vào trình chỉnh sửa (thông qua nút thêm phương tiện), trình soạn thảo không biết kích thước svg, vì vậy mặc dù nó thêm svg dưới dạng hình ảnh nhưng nó có chiều rộng và chiều cao bằng không.

  4. Khi bạn nhấp vào "chỉnh sửa hình ảnh" từ trong cửa sổ bật lên phương tiện tải lên, bạn sẽ nhận được thông báo "hình ảnh không tồn tại". Xem hình ảnh dưới đây.

Tôi ổn với mục 1 trong danh sách này, nhưng có ai tìm ra cách sửa mục 2 3 và 4 không?

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Cập nhật về mục 1:

Để cho phép một loại mime mới (chẳng hạn như SVG), bạn chỉ cần thêm một hook trong hàm.php

function allow_new_mime_type($mimes) {

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

    return $mimes;
}
add_filter( 'mime_types', 'allow_new_mime_type' );

Bây giờ bạn sẽ có thể tải lên các SVG. Bạn có thể tìm thêm thông tin trong hướng dẫn này . Điều này chỉ giải quyết mục 1, như tôi đã đề cập trước đây, nó không phải là vấn đề đối với tôi (mặc dù tôi nghĩ rằng nó nên được cho phép theo mặc định).

Cập nhật về mục 2:

Tôi đã thực hiện một số hoạt động đào và theo dõi chức năng quyết định xem một tệp đính kèm có phải là hình ảnh hay không. Dường như tất cả đều bắt nguồn từ chức năng này trong wp-gộp / 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;
}

Như bạn có thể thấy có một loạt các phần mở rộng hình ảnh hợp lệ được xác định trong chức năng này. Tôi không thấy bất kỳ bộ lọc nào có thể được sử dụng để sửa đổi mảng đó. Nhưng đó là một khởi đầu ...

Tôi không chắc chắn tại sao câu lệnh if cuối cùng trả về false cho svss. Ngay cả khi tôi không thêm tiện ích mở rộng svg vào mảng $ image_exts, điều kiện đầu tiên sẽ trả về đúng, không nên sao?

if ( 'image/' == substr($post->post_mime_type, 0, 6)

Điều đó kiểm tra xem 'image /' có phù hợp với sáu ký tự đầu tiên trong loại mime hay không, đối với svg là image / svg + xml (sáu đầu tiên là "image /").

CẬP NHẬT

Sau khi điều tra thêm, có vẻ như vấn đề không nằm ở wp_attachment_is_image, mà vì kích thước hình ảnh (chiều rộng và chiều cao) không được thêm vào siêu dữ liệu đính kèm khi SVG được tải lên. Đó là bởi vì hàm để tính toán hình ảnh được sử dụng là hàm php getimagesize (), không trả về kích thước hình ảnh cho SVG. Tôi đã tìm thấy một câu trả lời trên stackoverflow về hàm getimagesize và về cách các Svss hành xử. Xem nó ở đây.


Cài đặt plugin hỗ trợ SVG, nó sẽ hiển thị svg trên thư viện phương tiện - wordpress.org/plugins/svg-support
Nuno Sarmento

Câu trả lời:


10

Hãy xem wp_prepare_attachment_for_js(), đó là những gì tập hợp siêu dữ liệu đính kèm để sử dụng trên các trang Media. Bộ lọc cùng tên cho phép chúng tôi thêm hoặc thay đổi siêu dữ liệu.

Ví dụ sau đây có thể được thả vào hàm.php. Lưu ý: điều này yêu cầu hỗ trợ SimpleXML trong PHP.

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

2

Đây không phải là thứ bạn sẽ dễ dàng có thể "hack" bằng một plugin hoặc một bộ mã nhỏ.

Tóm lại, đó là các SVG, nói chung, không phải là "hình ảnh" theo nghĩa của tất cả các hình ảnh đã xuất hiện trước nó. Các SVG là các hình ảnh dựa trên vector và là những hình ảnh đầu tiên nhận được bất kỳ lực kéo thực sự nào trên web.

Tất cả các hình ảnh trước đó đã được dựa trên bitmap. Hệ thống xử lý hình ảnh của WordPress được viết riêng để đối phó với những điều đó và thiết kế vốn có này được đặt tại mọi điểm trong hệ thống.

Đó là một giả định cơ bản rằng hình ảnh có chiều rộng và chiều cao, ví dụ. SVG không có, chúng có thể có kích thước bất kỳ. Có toàn bộ "trình chỉnh sửa" cơ bản cho hình ảnh được tích hợp trong WordPress, không có chức năng nào thực sự có thể áp dụng cho SVG.

Hệ thống đa phương tiện đang dần được phát triển lại, với sự nhấn mạnh ở đây là "từ từ". Có rất nhiều khả năng tương thích ngược được duy trì và các thiết kế mới sẽ được thực hiện. Ngoài ra, hầu hết mọi người quan tâm nhiều hơn đến việc hỗ trợ video, âm thanh và danh sách phát. Khi công việc thiết kế lại này được thực hiện và các phần của thư viện trở nên trừu tượng hơn, thì loại điều này sẽ trở nên dễ dàng hơn để hỗ trợ theo thời gian. Nhưng nó chưa ở đó và nó sẽ không được một lúc. Đây là lý do tại sao loại mime SVG không được hỗ trợ, bởi vì thêm loại mime đó cho đến khi tất cả các phần cơ bản hoạt động sẽ là một con đường dẫn đến phá vỡ.

Đối với SVG, wp_attachment_is_imagenên trả về false, bởi vì wp_attachment_is_imageđược sử dụng để xác định xem có hiển thị nút chỉnh sửa hay không và có image_downsizecố gắng thay đổi kích thước hình ảnh thành hình thu nhỏ hay không. Cả hai đều không hoạt động cho SVGs. Để hỗ trợ đúng các SVG, bạn cần phải viết một hệ thống mới để thêm siêu dữ liệu cho những hình ảnh đó và sau đó thêm hỗ trợ cho nó ở tất cả những nơi có thể sử dụng siêu dữ liệu. Như bạn có thể tưởng tượng, đó không phải là một công việc nhỏ.


1
Các SVG không có kích thước (khung nhìn và hộp xem), nó chỉ "ảo" hơn các kích thước phụ thuộc pixel pixel cố định của bitmap.
Hết

1

Chỉ cần đọc nguồn (không kiểm tra), tôi có thể thấy rằng tiện ích mở rộng cần khớp:

if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) )

mà đọc là (mã giả)

if image/là 6 ký tự đầu tiên trong thuộc tính $ post đối tượng post_mime_type HOẶC có phần mở rộng HOẶC importlà đối tượng $ post post_mime_type VÀ phần mở rộng tệp hiện tại là một trong (Mảng)

Và điều đó có nghĩa là tuyên bố cuối cùng sẽ luôn quyết định xem liệu điều đó có ifđúng hay không.

Từ những gì tôi có thể đọc được get_attached_file(), có một bộ lọc cho phép giả mạo tiện ích mở rộng:

return apply_filters( 'get_attached_file', $file, $attachment_id );

Nói cách khác, bạn có thể cố gắng trả lại cùng một tệp nhưng với một phần mở rộng khác. Nó sẽ không xung đột với các bộ phận khác, như wp_attachment_is_image()chỉ trở lại bool.

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.