为特定的自定义图像尺寸设置JPEG压缩


8

我使用了各种自定义图片尺寸(按add_image_size),并且使用此滤镜将JPEG压缩率设置为30%:

function jpeg_quality_callback($arg) {
   return (int)30;
}
add_filter('jpeg_quality', 'jpeg_quality_callback');

如果我没记错的话,上面的代码会将所有自定义图片大小压缩30%。现在,对于名为splash1和的两个自定义图像尺寸splash2,我想将压缩率设置为80%。这怎么可能?

或者,从30%压缩滤镜中排除那些图像大小。

Answers:


9

'jpeg_quality'过滤器挂接函数接受两个参数:$jpeg_quality$function其从过滤器内钩的功能被触发,并且可以是image_resizewp_crop_image。因此,无法.jpeg通过此滤镜挂钩功能根据图像尺寸有选择地设置图像质量。

但是,您仍然可以在上载附件的过程中挂接到以后的动作挂钩,并.jpeg根据自己的特定大小调整上传图像的图像质量,以适应​​您的需要。首先将设置jpeg_quality为最大,以保留原始图像质量,然后挂钩到added_post_meta动作挂钩(在插入附件元数据末尾触发)以调整质量,如下所示:

// set the quality to maximum
add_filter('jpeg_quality', create_function('$quality', 'return 100;'));

add_action('added_post_meta', 'ad_update_jpeg_quality', 10, 4);

function ad_update_jpeg_quality($meta_id, $attach_id, $meta_key, $attach_meta) {

    if ($meta_key == '_wp_attachment_metadata') {

        $post = get_post($attach_id);

        if ($post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes'])) {

            $pathinfo = pathinfo($attach_meta['file']);
            $uploads = wp_upload_dir();
            $dir = $uploads['basedir'] . '/' . $pathinfo['dirname'];

            foreach ($attach_meta['sizes'] as $size => $value) {

                $image = $dir . '/' . $value['file'];
                $resource = imagecreatefromjpeg($image);

                if ($size == 'spalsh') {
                    // set the jpeg quality for 'spalsh' size
                    imagejpeg($resource, $image, 100);
                } elseif ($size == 'spalsh1') {
                    // set the jpeg quality for the 'splash1' size
                    imagejpeg($resource, $image, 30);
                } else {
                    // set the jpeg quality for the rest of sizes
                    imagejpeg($resource, $image, 10);
                }

                // or you can skip a paticular image size
                // and set the quality for the rest:
                // if ($size == 'splash') continue;

                imagedestroy($resource);
            }
        }
    }
}

上面的代码仅会影响新上传的图像。如果要更新以前上传的图像的质量,则可以使用register_activation_hook插件。在wp-content/plugins目录中创建一个新的php文件,并将其命名为任意名称(update-jpeg-quality.php例如),然后向其中添加以下代码:

<?php
/*
Plugin Name: Update JPEG Quality
Plugin URI: http://wordpress.stackexchange.com/questions/74103/set-jpeg-compression-for-specific-custom-image-sizes
Description: This plugin will change the jpeg image quality according to its size.
Author: Ahmad M
Version: 1.0
Author URI: http://wordpress.stackexchange.com/users/12961/ahmad-m
*/

register_activation_hook(__FILE__, 'ad_modify_jpeg_quality');

function ad_modify_jpeg_quality() {

    $attachments = get_posts(array(
        'numberposts' => -1,
        'post_type' => 'attachment',
        'post_mime_type' => 'image/jpeg'
    ));

    if (empty($attachments)) return;

    $uploads = wp_upload_dir();

    foreach ($attachments as $attachment) {

        $attach_meta = wp_get_attachment_metadata($attachment->ID);
        if (!is_array($attach_meta['sizes'])) break;

        $pathinfo = pathinfo($attach_meta['file']);
        $dir = $uploads['basedir'] . '/' . $pathinfo['dirname'];

        foreach ($attach_meta['sizes'] as $size => $value) {

            $image = $dir . '/' . $value['file'];
            $resource = imagecreatefromjpeg($image);

            if ($size == 'spalsh') {
                // set the jpeg quality for 'spalsh' size
                imagejpeg($resource, $image, 100);
            } elseif ($size == 'spalsh1') {
                // set the jpeg quality for the 'splash1' size
                imagejpeg($resource, $image, 30);
            } else {
                // set the jpeg quality for the rest of sizes
                imagejpeg($resource, $image, 10);
            }

            imagedestroy($resource);
        }
    }
}
?>

现在访问您的插件页面并点击activateUpdate JPEG Quality插件。这将循环浏览您以前上传的所有.jpeg图像,并根据您在插件中指定的值和条件调整其质量。然后,您可以安全地停用并删除此插件。在申请生产现场之前,请先在测试环境中进行测试


这是一个非常有趣的答复。如何在IF语句中同时添加“ splash1”和“ splash2” ?:if($ size =='splash')...
Amanda Duke

1
@AmandaDuke:您可以通过扩展if语句elseif。查看我的更新。
Ahmad M

2
@Ahmad您的代码中有错误。上载图片时,如果它小于最小自定义图片尺寸的尺寸,则会出现此错误:Invalid argument supplied for foreach()。因此,基本上,当没有自定义图像时,就会出现错误。您知道如何解决此问题吗?
阿曼达·杜克

1
@AmandaDuke感谢您指出这一点。发生此错误是因为$attach_meta['sizes']期望是数组,而在这种情况下不是。在大多数情况下,应该且仅当我们没有自定义图像尺寸并且没有在Settings-> Media Settings中指定默认图像尺寸时,才会发生这种情况。为了安全起见,确保我们有一个数组,我们可以把它传递给前添加一个检查foreach循环:if (is_array($attach_meta['sizes']))。请查看更新的代码。
艾哈迈德M

1
@AmandaDuke:两个代码块均已更新。第一个街区在之前:if ( $post->post_mime_type == 'image/jpeg' )现在是if ( $post->post_mime_type == 'image/jpeg' && is_array($attach_meta['sizes']) )
艾哈迈德M
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.