画像サイズに基づいた画質


15

画像サイズに基づいて画質を設定することは可能ですか?大きな画像では画質を向上させたい(80)-小さなサムネイルでは画質を低下させたい(30)。

私はadd_sizeそれを制御するパラメータを期待していました-しかし、何もありません。

重要な場合:ImageMagickを使用しています。

回答:


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)ほどまっすぐなものを使用しなかった理由は、画像の編集(回転、トリミングなど)ですべてのアクションが2回呼び出され、品質が2倍低下したことを漠然と覚えているからです。それでも、「のインスタンスWP_Image_Editor」の部分は、私が書いたものよりもはるかに多くの解決策です。
カイザー14年

1
品質はパーセンテージではなく正確な値です。保存するまで、好きなように設定およびリセットできます。それは10で10百倍の葉にそれを設定する
オットー

その間に節約できると思いました。ヘッドアップをありがとう。
カイザー14年

その私には思えるimage_editor_save_pre呼び出されません。error_log(間違いなく動作します)を使用して出力しようとすると、出力が得られません。:/
ニルスリーデマン14年

1
画像を再保存すると、再生成も機能する場合があります。実際にリロードして再保存するアクションを実行しない限り、システム上の既存のファイルを変更するコードはありません。
オットー14年

5

事前の注意:以下の回答は完了しておらず、テストもされていませんが、十分な時間が残っていないため、ここではドラフトとして残しておきます。おそらく2番目が必要なのは、品質の方法と解釈ですversion_compare()

まず、エントリポイントが必要です。メークポストをもう一度読んだ後、イメージエディターが新しく作成されたイメージを保存する前にジャンプするのが最善だと思いました。だから、ここにフックされたコールバック中にインターセプトしimage_editor_save_preてクラスをロードするマイクロコントローラーがあり、コールバック内で定義された設定をウォークスルーしますwpse_jpeg_qualityjpeg_qualityImage Editor内で実行されるフィルターの異なる圧縮率を返すだけです。

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

まだ作業中ですか?私に関する限り、それをプラグインとして見たいです。
ニルスリーデマン14年

申し訳ありませんが、私は違います。私もそれをプラグインとして見たいと思っていますが、私は現在それを必要とせず、時間もありませんので、今のところは起こりません。それを試してみて、編集または別の回答をどこまで取得してファイルするかを見てください。:)
kaiser 14年

kaiser:複雑すぎたと思う。image_editor_save_preに送信される$ imageは、WP_Image_Editorクラスのインスタンスです。サイズを取得し、品質とその中に既にある他のすべてを設定する機能があります。あなたがしなければならないのは、それらを呼び出すことです。
オットー14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.