You can perform a combination of things to accomplish a smaller file size. Let me guide you through it.
Firstly, you could add custom image sizes and adjust the dimensions to the very smallest for their purpose. Put the following in your functions file:
function my_insert_custom_image_sizes( $sizes ) {
// get the custom image sizes
global $_wp_additional_image_sizes;
// if there are none, just return the built-in sizes
if ( empty( $_wp_additional_image_sizes ) )
return $sizes;
// add all the custom sizes to the built-in sizes
foreach ( $_wp_additional_image_sizes as $id => $data ) {
// take the size ID (e.g., 'my-name'), replace hyphens with spaces,
// and capitalise the first letter of each word
if ( !isset($sizes[$id]) )
$sizes[$id] = ucfirst( str_replace( '-', ' ', $id ) );
}
return $sizes;
}
function custom_image_setup () {
add_theme_support( 'post-thumbnails' );
add_image_size( 'small', 160, 9999 ); // small
add_image_size( 'medium', 300, 9999 ); // medium
add_image_size( 'large-cropped', 578, 200, true ); // cropped
add_filter( 'image_size_names_choose', 'my_insert_custom_image_sizes' );
}
add_action( 'after_setup_theme', 'custom_image_setup' );
So, my_insert_custom_image_sizes
adds your custom images to the Media uploader window and I have added a few random sizes in the custom_image_setup
.
Next, we will need to set the JPEG compression value for each of these sizes. Observe the following:
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'] . "https://wordpress.stackexchange.com/" . $pathinfo['dirname'];
foreach ($attach_meta['sizes'] as $size => $value) {
$image = $dir . "https://wordpress.stackexchange.com/" . $value['file'];
$resource = imagecreatefromjpeg($image);
if ($size == 'large') {
// set the jpeg quality for 'large' size
imagejpeg($resource, $image, 35);
} elseif ($size == 'medium') {
// set the jpeg quality for the 'medium' size
imagejpeg($resource, $image, 40);
} elseif ($size == 'small') {
// set the jpeg quality for the 'small' size
imagejpeg($resource, $image, 40);
} elseif ($size == 'large-cropped') {
// set the jpeg quality for the 'large-cropped' size
imagejpeg($resource, $image, 45);
} else {
// set the jpeg quality for the rest of sizes
imagejpeg($resource, $image, 60);
}
// or you can skip a particular image size
// and set the quality for the rest:
// if ($size == 'splash') continue;
imagedestroy($resource);
}
}
}
}
As the comments demonstrate, this part sets the compression value: imagejpeg($resource, $image, VALUE)
. You will need to play around a little bit and find out what value works best with which image size. I set 60% compression for the rest of images.
The code above affects only newly updated images. If you wish to run a script that will change your existing images, in your plugin folder, add a new folder and create a new php file with this code inside:
<?php
/*
Plugin Name: Compression JPEG Quality
Plugin URI: http://domain.com
Description: This plugin will change the jpeg image quality according to its size.
Author: Christine
Version: 1.0
Author URI: http://domain.com
*/
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'] . "https://wordpress.stackexchange.com/" . $pathinfo['dirname'];
foreach ($attach_meta['sizes'] as $size => $value) {
$image = $dir . "https://wordpress.stackexchange.com/" . $value['file'];
$resource = imagecreatefromjpeg($image);
if ($size == 'large') {
// set the jpeg quality for 'large' size
imagejpeg($resource, $image, 35);
} elseif ($size == 'medium') {
// set the jpeg quality for the 'medium' size
imagejpeg($resource, $image, 40);
} elseif ($size == 'small') {
// set the jpeg quality for the 'small' size
imagejpeg($resource, $image, 40);
} elseif ($size == 'large-cropped') {
// set the jpeg quality for the 'large-cropped' size
imagejpeg($resource, $image, 45);
} else {
// set the jpeg quality for the rest of sizes
imagejpeg($resource, $image, 60);
}
imagedestroy($resource);
}
}
}
?>
Finally, add the WP Smush.it plugin which will bring down the file sizes even further.
A few notes to consider:
- None of this affects PNG file uploads. Your only option with this file format is to add a plugin that will convert PNG to JPEG however this will mean that transparency will not work. Another desperate solution would be to have all PNG files converted to PNG 8-bit file format which is limited to 256 colours. However, that would take your uploads back to the 90’s.
- The compression will not affect the
Full size
size option. This is the original file upload. If you are running a multiple author site and want to avoid your authors adding this filesize, you could add a filter to remove this file size from the drop down list. - These codes have been tested and functions fine with both WordPress v3.4.2 and v3.5