Chất lượng hình ảnh dựa trên kích thước hình ảnh


15

Có thể đặt chất lượng hình ảnh dựa trên kích thước hình ảnh? Tôi muốn có chất lượng hình ảnh tốt hơn cho hình ảnh lớn hơn (80) - và tệ hơn cho hình thu nhỏ (30).

Tôi đã mong đợi một tham số add_sizeđể kiểm soát điều đó - nhưng không có tham số nào.

Nếu có vấn đề: Tôi đang sử dụng ImageMagick.

Câu trả lời:


15

Thời gian duy nhất để thiết lập chất lượng thực sự quan trọng là ngay trước khi hình ảnh được lưu hoặc truyền phát (đối với trình chỉnh sửa). Cả hai đều có bộ lọc "image_editor_save_pre" ở đó, chuyển qua thể hiện của trình chỉnh sửa hình ảnh. Vì vậy, bạn có thể sử dụng điều đó để sửa đổi hình ảnh theo bất kỳ cách nào bạn muốn, bao gồm cả việc thiết lập chất lượng.

Vì vậy, một cái gì đó như thế này sẽ thực hiện công việc một cách đơn giản và dễ dàng:

add_filter('image_editor_save_pre','example_adjust_quality');
function example_adjust_quality($image) {
    $size = $image->get_size();
    // Values are $size['width'] and $size['height']. Based on those, do what you like. Example:
    if ( $size['width'] <= 100 ) {
        $image->set_quality(30);
    }
    if ( $size['width'] > 100 && $size['width'] <= 300 ) {
        $image->set_quality(70);
    }
    if ( $size['width'] > 300 ) {
        $image->set_quality(80);
    }
    return $image;
}

Lý do tại sao tôi không sử dụng thứ gì đó đơn giản như cái này (+1), mà tôi nhớ một cách mơ hồ rằng khi chỉnh sửa một số hình ảnh (xoay, cắt, v.v.), mọi hành động đều được gọi hai lần, giảm chất lượng hai lần. Tuy nhiên, phần "là một ví dụ của WP_Image_Editor" là một giải pháp nhiều hơn những gì tôi đã viết.
kaiser

1
Chất lượng là một giá trị chính xác, không phải là tỷ lệ phần trăm. Bạn có thể thiết lập và đặt lại tất cả những gì bạn thích, cho đến khi nó tiết kiệm. Đặt nó thành 10 một trăm lần để nó ở mức 10.
Otto

Tôi cho rằng nó sẽ tiết kiệm ở giữa. Cảm ơn cho những người đứng đầu lên.
kaiser

Dường như với tôi rằng image_editor_save_prekhông được gọi. Khi tôi cố gắng xuất công cụ bằng cách sử dụng error_log(chắc chắn hoạt động), tôi không nhận được bất kỳ đầu ra nào. : /
Nils Riedemann

1
Tái tạo cũng có thể hoạt động, nếu nó lưu lại hình ảnh. Không có mã nào sẽ thay đổi các tệp hiện có trên hệ thống mà bạn không thực sự thực hiện hành động để tải lại và lưu lại chúng.
Otto

5

Lưu ý trả trước: Câu trả lời dưới đây chưa kết thúc và chưa được kiểm tra, nhưng tôi không còn đủ thời gian, vì vậy tôi sẽ để nó ở đây như bản nháp. Những gì có lẽ cần một đôi mắt thứ hai là phương pháp chất lượng và giải thích version_compare().

Đầu tiên chúng ta cần một điểm vào. Sau khi đọc lại bài đăng một lần nữa, tôi nghĩ tốt nhất nên nhảy vào trước khi Trình chỉnh sửa hình ảnh lưu hình ảnh vừa tạo. Vì vậy, đây là một bộ điều khiển vi mô chặn trong quá trình gọi lại được nối image_editor_save_prevà tải một lớp sau đó đi qua các cài đặt của bạn được xác định bên trong một cuộc gọi lại wpse_jpeg_quality. Nó chỉ đơn giản trả về các tỷ lệ nén khác nhau cho jpeg_qualitybộ lọc chạy bên trong Trình chỉnh sửa hình ảnh.

<?php

namespace WPSE;

/**
 * Plugin Name: (#138751) JPEG Quality Router
 * Author:      Franz Josef Kaiser
 * Author URI:  http://unserkaiser.com
 * License:     CC-BY-SA 2.5
 */

add_filter( 'image_editor_save_pre', 'WPSE\JPEGQualityController', 20, 2 );
/**
 * @param string $image
 * @param int $post_id
 * @return string
 */
function JPEGQualityController( $image, $post_id )
{
    $config = apply_filters( 'wpse_jpeg_quality', array(
        # Valid: <, lt, <=, le, >, gt, >=, ge, ==, =, eq
        'limit'      => 'gt',
        # Valid: h, w
        'reference'  => 'w',
        'breakpoint' => 50,

        'low'        => 80,
        'high'       => 100,
    ) );
    include_once plugin_dir_path( __FILE__ ).'worker.php';
    new \WPSE\JPEGQualityWorker( $image, $config );

    return $image;
}

Công nhân thực tế là JPEGQualityWorkerlớp học. Nó nằm trong cùng thư mục với tệp plugin chính ở trên và được đặt tên worker.php(hoặc bạn thay đổi bộ điều khiển ở trên).

Nó lấy hình ảnh và cài đặt của bạn và sau đó thêm các cuộc gọi lại vào jpeg_qualitybộ lọc. Những gì đang làm là

  • lấy tham chiếu hình ảnh của bạn (chiều rộng hoặc chiều cao)
  • đặt câu hỏi về điểm dừng của bạn để quyết định nơi chuyển đổi giữa tỷ lệ nén / chất lượng thấp và chất lượng cao
  • lấy kích thước hình ảnh gốc
  • quyết định chất lượng để trả lại

Điểm dừng và giới hạn là những gì quyết định giữa cao và thấp và như đã đề cập ở trên, điều này có thể cần thêm một số tình yêu.

<?php

namespace WPSE;

/**
 * Class JPEGQualityWorker
 * @package WPSE
 */
class JPEGQualityWorker
{
    protected $config, $image;
    /**
     * @param string $image
     * @param array $config
     */
    public function __construct( Array $config, $image )
    {
        $this->config = $config;
        $this->image  = $image;

        add_filter( 'jpeg_quality', array( $this, 'setQuality' ), 20, 2 );
    }

    /**
     * Return the JPEG compression ratio.
     *
     * Avoids running in multiple context, as WP runs the function multiple
     * times per resize/upload/edit task, which leads to over compressed images.
     *
     * @param int $compression
     * @param string $context Context: edit_image/image_resize/wp_crop_image
     * @return int
     */
    public function setQuality( $compression, $context )
    {
        if ( in_array( $context, array(
            'edit_image',
            'wp_crop_image',
        ) ) )
            return 100;

        $c = $this->getCompression( $this->config, $this->image );

        return ! is_wp_error( $c )
            ? $c
            : 100;
    }

    /**
     * @param array $config
     * @param string $image
     * @return int|string|\WP_Error
     */
    public function getCompression( Array $config, $image )
    {
        $reference = $this->getReference( $config );
        if ( is_wp_error( $reference ) )
            return $reference;
        $size = $this->getOriginalSize( $image, $reference );
        if ( is_wp_error( $size ) )
            return $size;

        return $this->getQuality( $config, $size );
    }

    /**
     * Returns the quality set for the current image size.
     * If
     * @param array $config
     * @param int $size
     */
    protected function getQuality( Array $config, $size )
    {
        $result = version_compare( $config['breakpoint'], $size );
        return (
            0 === $result
            AND in_array( $config['limit'], array( '>', 'gt', '>=', 'ge', '==', '=', 'eq' ) )
            ||
            1 === $result
            AND in_array( $config['limit'], array( '<', 'lt', '<=', 'le', ) )
        )
            ? $config['high']
            : $config['low'];
    }

    /**
     * Returns the reference size (width or height).
     *
     * @param array $config
     * @return string|\WP_Error
     */
    protected function getReference( Array $config )
    {
        $r = $config['reference'];
        return ! in_array( $r, array( 'w', 'h', ) )
            ? new \WP_Error(
                'wrong-arg',
                sprintf( 'Wrong argument for "reference" in %s', __METHOD__ )
            )
            : $r;
    }

    /**
     * Returns the size of the original image (width or height)
     * depending on the reference.
     *
     * @param string $image
     * @param string $reference
     * @return int|\WP_Error
     */
    protected function getOriginalSize( $image, $reference )
    {
        $size = 'h' === $reference
            ? imagesy( $image )
            : imagesx( $image );

        # @TODO Maybe check is_resource() to see if we got an image
        # @TODO Maybe check get_resource_type() for a valid image
        # @link http://www.php.net/manual/en/resource.php

        return ! $size
            ? new \WP_Error(
                'image-failure',
                sprintf( 'Resource failed in %s', get_class( $this ) )
            )
            : $size;
    }
}

Vẫn đang làm việc trên nó? Theo như tôi quan tâm, tôi rất muốn xem đó là một plugin.
Nils Riedemann

Xin lỗi, nhưng tôi không có. Tôi cũng muốn xem đó là plugin, nhưng hiện tại tôi không cần dùng nó và không có thời gian, nó đã giành được giải thưởng cho đến nay. Có thể cho nó một shot, xem bạn nhận được bao xa và gửi một chỉnh sửa hoặc một câu trả lời riêng biệt? :)
kaiser

kaiser: Tôi nghĩ rằng nó quá phức tạp. $ Image được gửi đến image_editor_save_pre là một thể hiện của lớp WP_Image_Editor. Nó có chức năng để có được kích thước và thiết lập chất lượng và mọi thứ khác đã có trong đó. Tất cả bạn phải làm là gọi cho họ.
Otto
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.