根据图像尺寸更改JPEG压缩


8

短。我希望将“大”图像压缩90%,将“中”图像压缩60%。您知道很多事情,有时较大的图像会遭受高压缩,而其他较小的图像则不会。

此功能允许重新采样所有jpg图像

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

如何按图像尺寸过滤?

Answers:


11

一个非常特殊的过滤器

jpeg_quality过滤器是一个非常特殊的过滤器:它在三种不同的情况下使用,您必须使用第二个参数来确定是否要使用过滤器。

不要让它做任何事

这种特殊过滤器的主要问题是,如果您不删除它,它可能会在以后的操作中触发-允许它在第一次检查后运行。因此,我们需要在内部wp_save_image_file()添加另一个过滤器,以检查是否要更改压缩率。要在其他保存过程中将其禁用,我们将在更改压缩之前将其删除。

酷儿

真正奇怪的是,WP为每个保存过程使用默认压缩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方法。您可以在上面的↑中阅读的代码,主要是该插件中经过简化和更改的代码,其中还有少量遗留之处,旨在为以后的读者提供解释,并且仍然可以使用。如果您想将其用作插件,则可以根据个人用例进行一些优化。


笔记:

通过对不同任务的调查,我注意到,$case在以下步骤中触发了多个:

  • 旋转:edit-image» image-resize(对于您选择的任何大小,后1倍-缩略图等)
  • 镜像:edit-image» image-resize(-“-)

这意味着,用于的过滤器回调jpeq_quality将触发2倍旋转/镜像图像,而+1倍增加您添加的其他尺寸。因此,如果您获得的质量少于100%,则会降低质量两次。我对此主题进行了很多研究,但是我仍然不确定到底是什么确切的功能导致了这种现象。


Ups,您了解了我,print_r / var_dump无法正常工作。如何输出?
DarkGhostHunter 2012年

使用echo '<pre>'.var_export( $image, true ).'</pre>';。把一个exit;经过它,所以它不会跳过与重新加载页面等
凯泽

该死的,迷失在树林里-我看不到它的印刷位置。我在返回$ image之前有该代码;
DarkGhostHunter 2012年

将其添加到wpse58600_custom_jpg_compression()函数的开头。
kaiser 2012年

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.