基于图像尺寸的图像质量


15

是否可以根据图像尺寸设置图像质量?我希望大图像(80)的图像质量更好-小缩略图(30)的图像质量更好。

我期待有一个参数add_size来控制它-但是没有。

如果很重要:我正在使用ImageMagick。

Answers:


15

真正重要的是设置质量的唯一时间是在保存或传输图像之前(对于编辑器)。两者都在此处具有“ 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;
}

我之所以没有使用像这个(+1)那样直的东西的原因是,我隐约记得在编辑某些图像(旋转,裁剪等)时,每个动作都被调用了两次,从而降低了质量两次。仍然“是实例WP_Image_Editor”部分比我写的要多得多。
kaiser 2014年

1
质量是一个精确值,而不是百分比。您可以随意设置和重置它,直到保存。它在10设定为10百倍的叶子它
奥托

我以为它可以节省时间。感谢您的注意。
kaiser 2014年

在我看来,image_editor_save_pre没有接到电话。当我尝试使用error_log(肯定有效)输出内容时,我没有任何输出。:/
Nils Riedemann 2014年

1
如果重新保存图像,则重新生成也可能起作用。在没有您实际执行重新加载和重新保存文件的操作之前,没有任何代码可以更改系统上的现有文件。
2014年

5

预先注意:下面的答案尚未完成并且尚未测试,但是我还没有足够的时间,所以我将其留在此处作为草稿。可能需要第二眼的是质量方法和解释version_compare()

首先,我们需要一个入口点。再次通读make post之后,我认为最好是在Image Editor保存新创建的图像之前跳入。因此,这里有一个微控制器,该微控制器在挂接到的回调期间拦截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;
    }
}

还在努力吗?就我而言,我很乐意将其视为一个插件。
尼尔斯·里德曼2014年

对不起,但不是,我不是。我也希望看到它作为插件,但是由于我目前不需要它并且没有时间,所以到目前为止不会发生。也许试一试,看看您能得到多远并提交编辑或单独的答案?:)
kaiser 2014年

kaiser:我认为您太复杂了。发送到image_editor_save_pre的$ image是WP_Image_Editor类的实例。它具有获取尺寸和设置质量以及其中所有其他内容的功能。您所要做的就是打电话给他们。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.