Изменение размера картинок в wordpress. vt_resize vs timthumb

Потратил я немало времени, чтобы понять, каким образом предполагается работать с изображениями в wordpress. И понял, что полностью нативными методами задачу не решить…

А задача собственно довольно простая: сделать возможность вывода картинки заданного для конкретной записи размера в анонсе (лиде) записи.

Wp загружая картинки сразу же делает варианты этой картинки всех размеров, которые заданы в его настройках. Можно в любом месте кода вызвать функцию, которая создаст дополнительное представление и использовать его. Но в этом случае, если иногда нужны будут новые размеры, папка с картинками будет просто завалена огромным количеством вариантов, которые возможно никогда не будут использоваться.

Сотни сайтов перепечатали обход этой проблемы с использованием скрипта timthumb. Вызов php прописывается прямо в src изображения. Таким образом, сколько картинок грузится на странице, столько раз вызывается php скрипт. И хотя в большинстве случаев он будет отдавать файл из кэша — это все равно немалая нагрузка на сервер.. да и зачем пользователям сайта показывать, где генерируются картинки. Ведь потенциальный злоумышленник может легко нагрузить сервер или просто засыпать ваш кэш различными версиями всех ваших изображений например с шагом в 1px.

Ну а решение — функция, которую вы можете добавить в любой модуль. или даже в тему.
Работает она также, как и wordpress при загрузке изображения. При вызове, в папке загрузок создает изображение нужного размера и при следующем обращении отдает сразу адрес картинки.

Используется нативная функция wp: image_resize.

function vt_resize( $attach_id = null, $img_url = null, $width, $height, $crop = false )

Код функции взят здесь:
http://core.trac.wordpress.org/ticket/15311

/*
* Resize images dynamically using wp built in functions
* Victor Teixeira
*
* php 5.2+
*
* Exemple use:
*
* <?php
* $thumb = get_post_thumbnail_id();
* $image = vt_resize( $thumb,'' , 140, 110, true );
* ?>
* <img src="<?php echo $image[url]; ?>" width="<?php echo $image[width]; ?>" height="<?php echo $image[height]; ?>" />
*
* @param int $attach_id
* @param string $img_url
* @param int $width
* @param int $height
* @param bool $crop
* @return array
*/
function vt_resize( $attach_id = null, $img_url = null, $width, $height, $crop = false ) {

// this is an attachment, so we have the ID
if ( $attach_id ) {

$image_src = wp_get_attachment_image_src( $attach_id, 'full' );
$file_path = get_attached_file( $attach_id );

// this is not an attachment, let's use the image url
} else if ( $img_url ) {

$file_path = parse_url( $img_url );
$file_path = ltrim( $file_path['path'], '/' );
//$file_path = rtrim( ABSPATH, '/' ).$file_path['path'];

$orig_size = getimagesize( $file_path );

$image_src[0] = $img_url;
$image_src[1] = $orig_size[0];
$image_src[2] = $orig_size[1];
}

$file_info = pathinfo( $file_path );
$extension = '.'. $file_info['extension'];

// the image path without the extension
$no_ext_path = $file_info['dirname'].'/'.$file_info['filename'];

$cropped_img_path = $no_ext_path.'-'.$width.'x'.$height.$extension;

// checking if the file size is larger than the target size
// if it is smaller or the same size, stop right here and return
if ( $image_src[1] > $width || $image_src[2] > $height ) {

// the file is larger, check if the resized version already exists (for crop = true but will also work for crop = false if the sizes match)
if ( file_exists( $cropped_img_path ) ) {

$cropped_img_url = str_replace( basename( $image_src[0] ), basename( $cropped_img_path ), $image_src[0] );

$vt_image = array (
'url' => $cropped_img_url,
'width' => $width,
'height' => $height
);

return $vt_image;
}

// crop = false
if ( $crop == false ) {

// calculate the size proportionaly
$proportional_size = wp_constrain_dimensions( $image_src[1], $image_src[2], $width, $height );
$resized_img_path = $no_ext_path.'-'.$proportional_size[0].'x'.$proportional_size[1].$extension;

// checking if the file already exists
if ( file_exists( $resized_img_path ) ) {

$resized_img_url = str_replace( basename( $image_src[0] ), basename( $resized_img_path ), $image_src[0] );

$vt_image = array (
'url' => $resized_img_url,
'width' => $new_img_size[0],
'height' => $new_img_size[1]
);

return $vt_image;
}
}

// no cached files - let's finally resize it
$new_img_path = image_resize( $file_path, $width, $height, $crop );
$new_img_size = getimagesize( $new_img_path );
$new_img = str_replace( basename( $image_src[0] ), basename( $new_img_path ), $image_src[0] );

// resized output
$vt_image = array (
'url' => $new_img,
'width' => $new_img_size[0],
'height' => $new_img_size[1]
);

return $vt_image;
}

// default output - without resizing
$vt_image = array (
'url' => $image_src[0],
'width' => $image_src[1],
'height' => $image_src[2]
);

return $vt_image;
}