Как динамически изменять размер изображения WordPress на лету (произвольное поле/опция темы)
Итак - по запросу клиента, мне нужно иметь возможность изменять размер изображения не стандартным способом WordPress... а из изображения, загруженного через опции темы. Я не могу просто использовать область custom_header, так как будет два или три изображения (у меня также есть некоторые опции после загрузки изображения, позволяющие пользователю выбрать, как должна работать ссылка (страница, запись, категория, без ссылки, внешняя ссылка и т.д.)). Я использую Options Framework Theme с большим успехом и могу отлично получить src изображения, вопрос в том, можно ли как-то использовать это в сочетании с функцией add_image_size(), обычно используемой для миниатюр записей. Я бы ОЧЕНЬ не хотел идти по пути timthumb и предпочел бы придерживаться API WordPress (я знаю, что это немного противоречит тому, что я делаю изначально...). Буду признателен за любую помощь. Спасибо!

Изменение размера изображений в WordPress на лету с использованием встроенных функций WordPress.
Используйте функцию vt_resize
для динамического изменения размера изображений WordPress, расположенных в произвольном поле, миниатюре записи, директории загрузок, плагине NextGen Gallery или даже внешней ссылке на изображение с другого сайта.
Использование очень простое: просто скопируйте/вставьте приведенный ниже код в файл functions.php
вашей текущей активной темы WordPress.
Затем, где вам нужно изменить размер изображения на лету, просто вызовите эту функцию, следуя параметрам, описанным в комментариях к функции.
Вот пример автоматического получения ID записи, самой записи, значений произвольных полей записи и динамического изменения размера изображения из произвольного поля, содержащего изображение для изменения размера на лету.
<?php
# Поместите этот код в functions.php
function get_postID() {
global $wp_query;
return $wp_query->post->ID;
}
?>
<?php
# Поместите следующие строки туда, где вы хотите выполнить это действие.
$postID = get_postID(); // Получаем текущий ID записи.
$post = get_post( $postID ); // Берем текущий ID записи и возвращаем запись из базы данных. (альтернативно, `global $post`)
$custom = get_post_custom( $post->ID ); // Возвращает многомерный массив со всеми произвольными полями записи.
$image = $custom['field-slug'][0]; // Указываем ключ массива произвольного поля, содержащего изображение.
# Первый параметр - 0. Это означает, что не используется вложение записи.
# Второй параметр - URL изображения из значения произвольного поля записи.
# Третий и четвертый параметры - ширина и высота изображения после изменения размера.
# Пятый параметр означает обрезку изображения.
$resizedImage = vt_resize( 0, $image, 190, 338, true ); // Динамическое изменение размера изображения на лету.
echo '<img src="' . $resizedImage[ 'url' ] . '" width="' . $resizedImage[ 'width' ] . '" height="' . $resizedImage[ 'height' ] . '" title="' . $post->post_title . '" alt="' . $post->post_title . '" />'; // Свойства изображения хранятся в массиве. (Используйте print_r($resizedImage) для просмотра свойств массива.)
?>
Изменение размера изображений WordPress на лету с помощью vt_resize с поддержкой мультисайта
- Описание: Динамическое изменение размера изображений с использованием встроенных функций WordPress.
- Автор: Victor Teixeira
- Требования: PHP 5.2+, WordPress 3.2+
Я переформатировал исходный код для лучшей читаемости. Если вам нужен оригинальный формат исходного кода, посетите ссылку выше.
<?php
if ( ! function_exists( 'vt_resize' ) ) {
/**
* Изменение размера изображений динамически с использованием встроенных функций WordPress
* Victor Teixeira
*
* php 5.2+
*
* Пример использования:
*
* <?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|void
*/
function vt_resize( int $attach_id = 0, string $img_url = '', int $width = 0, int $height = 0, bool $crop = false ) {
if ( $attach_id ) {
# это вложение, поэтому у нас есть ID
$image_src = wp_get_attachment_image_src( $attach_id, 'full' );
$file_path = get_attached_file( $attach_id );
} elseif ( $img_url ) {
# это не вложение, используем URL изображения
$file_path = parse_url( $img_url );
$file_path = $_SERVER['DOCUMENT_ROOT'] . $file_path['path'];
# Поиск пути для мультисайта
if ( file_exists( $file_path ) === false ) {
global $blog_id;
$file_path = parse_url( $img_url );
if ( preg_match( '/files/', $file_path['path'] ) ) {
$path = explode( '/', $file_path['path'] );
foreach ( $path as $k => $v ) {
if ( $v == 'files' ) {
$path[ $k - 1 ] = 'wp-content/blogs.dir/' . $blog_id;
}
}
$path = implode( '/', $path );
}
$file_path = $_SERVER['DOCUMENT_ROOT'] . $path;
}
// $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 );
# проверяем, существует ли файл
$base_file = $file_info['dirname'] . '/' . $file_info['filename'] . '.' . $file_info['extension'];
if ( ! file_exists( $base_file ) ) {
return;
}
$extension = '.' . $file_info['extension'];
# путь к изображению без расширения
$no_ext_path = $file_info['dirname'] . '/' . $file_info['filename'];
$cropped_img_path = $no_ext_path . '-' . $width . 'x' . $height . $extension;
# проверяем, больше ли размер изображения, чем целевой размер
# если он меньше или такой же, останавливаемся и возвращаем
if ( $image_src[1] > $width ) {
# файл больше, проверяем, существует ли уже измененная версия (для $crop = true, но также будет работать для $crop = false, если размеры совпадают)
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 OR ! $height ) {
# рассчитываем размер пропорционально
$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;
# проверяем, существует ли уже файл
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' => $proportional_size[0],
'height' => $proportional_size[1]
);
return $vt_image;
}
}
# проверяем, меньше ли ширина изображения, чем установленная ширина
$img_size = getimagesize( $file_path );
if ( $img_size[0] <= $width ) {
$width = $img_size[0];
}
# Проверяем, установлена ли библиотека GD
if ( ! function_exists( 'imagecreatetruecolor' ) ) {
echo 'Ошибка библиотеки GD: imagecreatetruecolor не существует - обратитесь к вашему хостинг-провайдеру и попросите установить библиотеку GD';
return;
}
# нет кэшированных файлов - наконец, изменяем размер
$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] );
# вывод измененного изображения
$vt_image = array(
'url' => $new_img,
'width' => $new_img_size[0],
'height' => $new_img_size[1]
);
return $vt_image;
}
# вывод по умолчанию - без изменения размера
$vt_image = array(
'url' => $image_src[0],
'width' => $width,
'height' => $height
);
return $vt_image;
}
}
?>

Вот гораздо более простая функция (без поддержки мультисайтов, но кто в здравом уме использует мультисайты?) https://github.com/BrettMW/img_resize

Также готовое к использованию решение https://github.com/bueltge/WP-Image-Resizer, как ссылка от @kaiser

@bueltge, оно работает, но есть ли у тебя идеи, почему изображения получаются размытыми? Кажется, оно делает все изображения размером 150x150. Есть мысли, почему так происходит?

@bueltge, неважно. Я нашёл проблему. Мне нужно было указать размер full вторым параметром при использовании wp_get_attachment_image_url()

@bueltge, забудьте. Похоже, это не работает... Можете, пожалуйста, помочь с этим? Когда я указываю размер изображения как full
, изображения имеют разные размеры.

С параметром full вы всегда получаете загруженный размер, ширину и высоту оригинала. Вам следует работать с определённым размером, например, custom_full, который задаётся с шириной и высотой.
