Качество изображения на основе размера изображения

Возможно ли установить качество изображения на основе размера изображения? Я хотел бы иметь лучшее качество изображения для больших изображений (80) – и хуже для маленьких миниатюр (30).

Я ожидал параметр в add_size для управления этим, но его нет.

Если это имеет значение: я использую ImageMagick.

Единственное время, когда качество настройки действительно имеет значение, находится прямо перед тем, как изображение будет сохранено или передано (для редактора). Оба они имеют фильтр «image_editor_save_pre», передавая ему экземпляр редактора изображений. Таким образом, вы можете использовать это для изменения изображения любым способом, включая настройку качества.

Итак, что-то вроде этого должно делать работу просто и легко:

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

Обратите внимание: ниже ответ не закончен и не проверен, но у меня не осталось достаточно времени, поэтому я оставлю это здесь как черновик. Вероятно, для второй пары глаз нужен метод качества и интерпретация version_compare() .

Сначала нам нужна точка входа. Прочитав снова сообщение, я подумал, что лучше всего перепрыгнуть, прежде чем редактор изображений сохранит только что созданный образ. Итак, вот микроконтроллер, который перехватывает во время обратного вызова, подключенного к image_editor_save_pre и загружает класс, который затем просматривает ваши настройки, определенные внутри обратного вызова к wpse_jpeg_quality . Он просто возвращает разные коэффициенты сжатия для фильтра jpeg_quality который выполняется внутри редактора изображений.

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

Фактическим рабочим является класс JPEGQualityWorker . Он находится в том же каталоге, что и основной файл плагина, и называется worker.php (или вы меняете контроллер выше).

Он извлекает изображение и ваши настройки, а затем добавляет обратные вызовы в фильтр jpeg_quality . Что делает

  • получение ссылки на изображение (ширина или высота)
  • опрос вашей точки останова, который решает, где переключаться между низким и высоким качеством / коэффициентом сжатия
  • получение исходного размера изображения
  • решая, какое качество вернуть

Точка останова и предел – это то, что выбирают между высоким и низким и, как упоминалось выше, может потребоваться еще больше любви.

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