web-dev-qa-db-ja.com

画像サイズに応じてJPEG圧縮を変更する

ショート。私は、「大きい」画像を90%圧縮し、「普通」の画像を60%圧縮する必要があります。あなたが知っている多くのafを持っています、時々より大きな画像は高圧縮に苦しみます、しかし、他の小さな画像はそうしません。

この機能はすべてのjpg画像をリサンプリングすることを可能にします

function custom_jpg_compression($args) {
    return 90;
}
add_filter('jpeg_quality', 'custom_jpg_compression');

画像サイズでフィルタリングするには?

8
DarkGhostHunter

非常にspecialフィルター

jpeg_qualityフィルターはreally特別なフィルターです。3つの異なるケースで使用され、2番目の引数を使用してifフィルターを使用するかどうか。

すべてをさせてはいけない

このようなspecialフィルターの主な問題は、それを削除しない場合、後のアクションで起動する可能性があることです。最初のチェック後に実行できるようにします。したがって、圧縮を変更するかどうかを確認するには、wp_save_image_file()内に別のフィルターを取得する必要があります。別の保存プロセスで無効にするために、圧縮を変更する直前に削除します。

ザ・クール・キッド

本当に奇妙なのは、WPがeveryの保存プロセスに対してデフォルトの90%(10%の品質低下)の圧縮を使用することです。これは、画像をアップロード/トリミング/編集するたびにその品質が低下することを意味します...これは、アップロードするときに最高ではない画像の痛みです(多くの赤を含む画像でテストしてください)背景のコントラストが高い)。 しかし ...本当にすてきなことは、この動作を変更できることです。したがって、圧縮を変更する必要がありますが、品質の向上-コアが許可するよりもはるかに優れています-同時に。

/**
 * Alter the image compression, depending on case
 * 
 * @param  int $compression
 * @param  string $case
 * @return int $compression
 */
function wpse58600_custom_jpg_compression_cb( $compression, $case )
{
    global $size_switch;

    // Should only fire once - don't leave it in for later cases
    remove_filter( current_filter(), __FUNCTION__ );

    // Alter the compression, depending on the case
    switch ( $case )
    {
        case( 'edit_image' ) :
            // We only add the compression, if the switch triggered,
            // which means, that the size is smaller, than set in the main function.
            // 60 is the percentage value, that gets added as compression to the smaller images.
            $compression = $size_switch ? 60 : 100;
            break;

        case( 'image_resize' ) :
            // Better leave it on 100% for resize
            $compression = 100;
            break;

        case( 'wp_crop_image' ) :
            // Better leave it on 100% for crop
            // We already compressed it on the camera, the desktop/handheld device 
            // and the server previously. That's enough so far.
            $compression = 100;
            break;
    }

    return $compression;
}

/**
 * Alter the compression for JPEG mime type images
 * Checks for a specific min size of the image, before altering it
 * 
 * @param  string $image
 * @param  int $post_id 
 * @return string $image
 */
function wpse58600_custom_jpg_compression( $image, $post_id )
{
    global $size_switch;
    $size_switch = false;

    // Define the size, that stops adding a compression
    $trigger_size = 641;

    // Get the sizes
    $size_x = imagesx( $image );
    $size_y = imagesy( $image );

    // Add the filter only in case
    if ( $trigger_size < $size_x )
    {
        $size_switch = true;
    }
    add_filter( 'jpeg_quality', 'wpse58600_custom_jpg_compression_cb', 20, 2 );

    return $image;
}
add_filter( 'image_save_pre', 'wpse58600_custom_jpg_compression', 20, 2 );

編集: @toschoとの短い議論の後、彼はコールバック全体を次のように減らすことができると指摘しました。

function wpse58600_custom_jpg_compression_cb( $compression, $case )
{
    // Should only fire once - don't leave it in for later cases
    remove_filter( current_filter(), __FUNCTION__ );

    return ( $GLOBALS['size_switch'] && 'edit_image' === $case ) ? 60 : 100;
}

現在作業中のプラグインからコードを引き出したときに、設定を追加するためにswitchが必要でした。また、プラグインではglobalを使用しないことに注意する必要があります、これはOOPアプローチです。上記の↑を読むことができるコードは、主にプラグインからのコードを減らして変更したものです。これには若干のマイナーな残りがあり、後の読者のために説明的であり、引き続き機能します。プラグインとして使用する場合は、個人のユースケースに応じて最適化を行うことができます。


ノート:

さまざまなタスクの調査から、次のステップで複数の$casesがトリガーされることがわかりました。

  • 回転:edit-image"image-resize(選択した任意のサイズの後の1倍-サムネイルなど)
  • ミラー:edit-image"image-resize(-"-)

つまり、jpeq_qualityのフィルターコールバックは、画像を回転/ミラーリングするために2xをトリガーし、追加した追加サイズに対して+ 1xをトリガーします。したがって、100%未満になった場合、品質が2倍低下します。私はこのトピックについて多くの研究を行いましたが、どのような正確な機能がこの動作を引き起こすのか、まだ完全にはわかりません。

11
kaiser