Add custom image sizes to media uploader

I want to add custom image sizes to the media uploader:

media uploader

Read More

In order to do this, I use the following code (comments are there for convenience):

// this function adds the custom image sizes to the media uploader
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;
}

// define the init function next, which sets up all the necessary stuff
function custom_image_setup () {
    add_theme_support( 'post-thumbnails' );
    add_image_size( 'my-size1', 250, 250 );
    add_image_size( 'my-size2', 350, 350 );
    add_image_size( 'my-size3', 450, 450 );
    add_filter( 'image_size_names_choose', 'my_insert_custom_image_sizes' );
}

// attach that init function to the 'after_setup_theme' hook
// so it runs on each page load once your theme's been loaded
add_action( 'after_setup_theme', 'custom_image_setup' );

This code works fine. Beside one issue: When uploading an image, if it is smaller than the dimensions of the smallest custom image size, then this error appears: Invalid argument supplied for foreach().

I presume the problem comes from the my_insert_custom_image_sizes function. So basically, when no custom image is made, the error appears. How can I fix this? I have a feeling the problem is something simple that I overlooked but I’m lost…

If you want to replicate this error, just paste the above code in functions and upload an image that is smaller than 250×250 in pixels.

UPDATE: After some further research, it appears that the error is related to the foreach in my JPEG compression function:

// Set JPEG compression quality
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') {

            $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 == '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, 35);
                } elseif ($size == 'small') {
                    // set the jpeg quality for the 'small' size
                    imagejpeg($resource, $image, 40);
                } else {
                    // set the jpeg quality for the rest of sizes
                    imagejpeg($resource, $image, 90);
                }

                imagedestroy($resource);
            }
        }
    }
}

Any ideas what is wrong with it?

Related posts

Leave a Reply

1 comment

  1. Invalid argument supplied for foreach means that the X in foreach X as ... is not an array. You can prevent this error by type casting; add (array) before the argument in the foreach statement. This will turn your variable into an array, essentially. In your code, the change would be…

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

    Now keep in mind that this won’t fix the real issue here, which is that your code is expecting $attach_meta['sizes'] to be an array and it is not. You may want to refactor your code to handle that scenario.