Intereting Posts
Проверка того, установлен ли атрибут woocommerce почему двадцать одиннадцать вопросов смешивают единицы измерения css? Как захватить первое изображение из некоторых выбранных категорий Сохранить атрибуты объекта JSON для пользовательских метабокс Как использовать настраиваемые каталоги загрузки в файловой системе и URL-адресе на основе типа или категории мультимедиа Отображать пользовательский список тегов в редакторе post / page с помощью перехватчиков Хостинг блога WordPress в виде подпапки с веб-сайта S3 Что такое хороший способ реализации фотогалереи на WordPress? Сообщения, не отражающие правильные данные при распространении URL на Facebook Custom Post Type Archive – archive.php присутствует, но он не используется Как удалить pingback из головы? В чем разница между этими двумя методами написания $ вместо jQuery в WordPress Ошибка пользовательского поля в WordPress 3.2 Как добавить класс тела во все внутренние страницы, кроме главной страницы Динамически добавлять заголовки для отправки изображений, если они пусты

Создайте размер изображения, основываясь на ориентации изображения

Я работаю над довольно сложной редизайном проекта wordpress. В настоящее время я работаю над реализацией образа. Сайт очень тяжелый, и я хочу предоставить оптимальное изображение для каждого приложения. Я подумал о чем-то вроде этого:

1. Ориентация

Изображение может быть в альбомном, portait или квадратном формате. Каждая из них имеет разную максимальную ширину. Оптимальным решением было бы предоставление другой версии для каждой ориентации.

Landscape Portrait Square 

2. Высокий ИЦП

Я также хотел бы предоставить @ 2x версию каждого изображения:

 Landscape Landscape@2x Portrait Portrait@2x Square Square@2x 

3. Точки останова

На последнем сайте есть как минимум четыре точки останова. Я также хотел бы оптимизировать изображение для каждой точки останова:

 Breakpoint 1 | Breakpoint 2 | Breakpoint 3 | Breakpoint 4 -------------|--------------|--------------|------------- Landscape | Landscape | Landscape | Landscape Landscape@2x | Landscape@2x | Landscape@2x | Landscape@2x | | | Portrait | Portrait | Portrait | Portrait Portrait@2x | Portrait@2x | Portrait@2x | Portrait@2x | | | Square | Square | Square | Square Square@2x | Square@2x | Square@2x | Square@2x 

Проблема

В итоге это дает мне 24 сгенерированных изображения на изображение, что представляет собой огромное количество сгенерированных данных. Две трети этих данных никогда не будут использоваться (две другие ориентации), и я бы хотел их исключить. add_image_size() не учитывает ориентацию изображения.

Есть ли способ генерировать изображения, необходимые для ориентации изображения?


Обновить

TL; DR: Я, возможно, нашел решение, код внизу, дальнейшее тестирование завтра.

Хорошо, сегодня я глубоко погрузился в WordPress Trac, и я думаю, что у меня это есть.

Трудно изменить генерацию функции add_image_size() , поэтому я взял wp_generate_attachment_metadata hook,

Изображения генерируются в функции wp_generate_attachment_metadata() . Трудно изменить функцию, потому что соответствующий wp_generate_attachment_metadata происходит после того, как изображения были сгенерированы.

Тем не менее, это был лучший крючок, который я нашел для этой цели. Я решил создать свои собственные измененные копии исходного изображения ( WP_Image_Editor сделал это довольно легко) и включить вновь созданные изображения в метаданные исходного изображения.

Пока это выглядит довольно хорошо, за исключением того, что индикатор прогресса остается на 100% до тех пор, пока изображения не будут обработаны. Это может быть проблемой, когда пользователи покидают страницу, прежде чем все изображения будут обработаны. Вторая проблема заключалась в том, что созданные пользователем изображения не удаляются, если я удалю вложение. Это происходит из-за функции get_intermediate_image_sizes() , которая ищет размеры изображений, добавленные add_image_size() . Я нашел hook_images_size и хочу попытаться добавить к нему все возможные размеры изображения, тем временем у меня есть быстрое решение, использующее delete_attachment .

Завтра я буду продолжать тестирование и обновить этот пост.

Вот мой код:

 /** * Generates custom image sizes, depending on the image orientation. Use the wp_generate_attachment_metadata hook! */ function r21_create_custom_image_sizes($meta) { // Initialize variables global $r21_image_sizes; $image_sizes = ''; $new_meta = array(); // Generate the full file path for the image $image['path'] = path_join(wp_upload_dir()['basedir'], $meta['file']); // Get the dimensions of the original image list($image['width'], $image['height'], $image['type']) = getimagesize($image['path']); // Check the image orientation if ($image['width'] > $image['height']) { // Landscape $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'landscape', true); } else if ($image['width'] < $image['height']) { // Portrait $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'portrait', true); } else { // Square $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'square', true); } // Iterate through the sizes to be generated foreach ($image_sizes as $size) { // TODO: Check if an image in the requested dimensions allready exists. // Create an instance of WP_Image_Editor for the original image $new_image = wp_get_image_editor($image['path']); // Resize the image $new_image->resize($size['width'], $size['height'], $size['crop']); // Save new image and store new meta data in variable $new_image_meta = $new_image->save(); // Reflect back new metadata $meta['sizes'][$size['name']]['file'] = $new_image_meta['file']; $meta['sizes'][$size['name']]['width'] = $new_image_meta['width']; $meta['sizes'][$size['name']]['height'] = $new_image_meta['height']; $meta['sizes'][$size['name']]['mime-type'] = $new_image_meta['mime-type']; } return $meta; } add_filter('wp_generate_attachment_metadata', 'r21_create_custom_image_sizes'); /** * Deletes images, generated by r21_create_custom_image_sizes(). Use the delete_attachment hook! */ function r21_delete_custom_image_size_files($post_id) { $sizes_meta = wp_get_attachment_metadata($post_id)['sizes']; foreach ($sizes_meta as $size) { // TODO: Add support for wp_delete_file hook here @ unlink(path_join(wp_upload_dir()['path'], $size['file'])); } } add_action('delete_attachment', 'r21_delete_custom_image_size_files'); 

Вот мое рабочее решение. Код документирован, поэтому должно быть понятно, что делает каждая функция.

В основном я использую фильтр wp_generate_attachment_metadata для создания необходимых изображений после загрузки изображения.

Сгенерированные изображения также перечислены в метаданных, как и любой другой размер промежуточного изображения. Таким образом, вы можете очень много работать с ними, как с любым другим размером изображения.

Другая важная часть – использовать фильтр delete_attachment для деления сгенерированных изображений.

 // ========================== // Custom Image Size Handling // ========================== /** * Removes default and plugin generated image sizes. * This is optional! */ function r21_remove_image_sizes($sizes) { unset($sizes['thumbnail']); unset($sizes['medium']); unset($sizes['large']); return $sizes; } add_filter('intermediate_image_sizes', 'r21_remove_image_sizes'); add_filter('intermediate_image_sizes_advanced', 'r21_remove_image_sizes'); /** * Generate a handle for thumbnail regeneration tools. * The custom images will always be regenerated after one of * the site wide image sizes have been regenerated. * The problem here is, that if there are no site wide image sizes * defined, you can not regenerate any custom size images. * To avoid this we create a 1x1 px image that works as handle, if there * are no other imge sizes. */ add_image_size( 'cstm-img-regeneration-handle' , 1, 1, array( 'left', 'top' )); /** * Delete unneeded generated images and their metadata. * Also deletes images, generated in the filter, this is why * this function has to be used before the image generation function. * * @param array $attachment_meta * @return array */ function r21_remove_old_image_sizes($attachment_meta) { foreach ($attachment_meta['sizes'] as $size_name => $size_data) { // Ceck if image size is currently an active intermediate image size if (array_key_exists($size_name, get_intermediate_image_sizes())) { continue; } // Delete file @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$size_name]['file'])); // Delete metadata unset($attachment_meta['sizes'][$size_name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_old_image_sizes', 10, 1); /** * Removes the the custom image regneration handle image, if existing. * * @return array Returns the metadata, without the handle image entry. */ function r21_remove_regeneration_hook_image($attachment_meta) { $name = 'cstm-img-regeneration-handle'; // Check if image exists if (array_key_exists($name, $attachment_meta['sizes'])) { // Delete Image File @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$name]['file'])); // Delete Image Metadata unset($attachment_meta['sizes'][$name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_regeneration_hook_image', 10, 1); /** * Generates custom image sizes, depending on the image orientation. Use the wp_generate_attachment_metadata hook! */ function r21_create_custom_image_sizes($meta) { // Initialize variables global $r21_image_sizes; $image_sizes = ''; // Generate the full file path for the image $image['path'] = path_join(wp_upload_dir()['basedir'], $meta['file']); // Get the dimensions of the original image list($image['width'], $image['height'], $image['type']) = getimagesize($image['path']); // Check the image orientation if ($image['width'] > $image['height']) { // Landscape $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'landscape', true); } else if ($image['width'] < $image['height']) { // Portrait $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'portrait', true); } else { // Square $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'square', true); } // Iterate through the sizes to be generated foreach ($image_sizes as $size_name => $size) { // TODO: Check if an image in the requested dimensions allready exists. // Create an instance of WP_Image_Editor for the original image $new_image = wp_get_image_editor($image['path']); // Check if there is an error if (is_wp_error($new_image)) { continue; } // Resize the image $new_image->resize($size['width'], $size['height'], $size['crop']); // Save new image and store new meta data in variable $new_image_meta = $new_image->save(); // Reflect back new metadata $meta['sizes'][$size_name]['file'] = $new_image_meta['file']; $meta['sizes'][$size_name]['width'] = $new_image_meta['width']; $meta['sizes'][$size_name]['height'] = $new_image_meta['height']; $meta['sizes'][$size_name]['mime-type'] = $new_image_meta['mime-type']; } return $meta; } add_filter('wp_generate_attachment_metadata', 'r21_create_custom_image_sizes', 10, 1); /** * Deletes images, generated by r21_create_custom_image_sizes(). Use the delete_attachment hook! */ function r21_delete_custom_image_size_files($post_id) { $meta = wp_get_attachment_metadata($post_id); foreach ($meta['sizes'] as $size) { // TODO: Add support for wp_delete_file hook here @ unlink(path_join(r21_get_attachment_path_by('meta', $meta), $size['file'])); } } add_action('delete_attachment', 'r21_delete_custom_image_size_files'); не // ========================== // Custom Image Size Handling // ========================== /** * Removes default and plugin generated image sizes. * This is optional! */ function r21_remove_image_sizes($sizes) { unset($sizes['thumbnail']); unset($sizes['medium']); unset($sizes['large']); return $sizes; } add_filter('intermediate_image_sizes', 'r21_remove_image_sizes'); add_filter('intermediate_image_sizes_advanced', 'r21_remove_image_sizes'); /** * Generate a handle for thumbnail regeneration tools. * The custom images will always be regenerated after one of * the site wide image sizes have been regenerated. * The problem here is, that if there are no site wide image sizes * defined, you can not regenerate any custom size images. * To avoid this we create a 1x1 px image that works as handle, if there * are no other imge sizes. */ add_image_size( 'cstm-img-regeneration-handle' , 1, 1, array( 'left', 'top' )); /** * Delete unneeded generated images and their metadata. * Also deletes images, generated in the filter, this is why * this function has to be used before the image generation function. * * @param array $attachment_meta * @return array */ function r21_remove_old_image_sizes($attachment_meta) { foreach ($attachment_meta['sizes'] as $size_name => $size_data) { // Ceck if image size is currently an active intermediate image size if (array_key_exists($size_name, get_intermediate_image_sizes())) { continue; } // Delete file @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$size_name]['file'])); // Delete metadata unset($attachment_meta['sizes'][$size_name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_old_image_sizes', 10, 1); /** * Removes the the custom image regneration handle image, if existing. * * @return array Returns the metadata, without the handle image entry. */ function r21_remove_regeneration_hook_image($attachment_meta) { $name = 'cstm-img-regeneration-handle'; // Check if image exists if (array_key_exists($name, $attachment_meta['sizes'])) { // Delete Image File @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$name]['file'])); // Delete Image Metadata unset($attachment_meta['sizes'][$name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_regeneration_hook_image', 10, 1); /** * Generates custom image sizes, depending on the image orientation. Use the wp_generate_attachment_metadata hook! */ function r21_create_custom_image_sizes($meta) { // Initialize variables global $r21_image_sizes; $image_sizes = ''; // Generate the full file path for the image $image['path'] = path_join(wp_upload_dir()['basedir'], $meta['file']); // Get the dimensions of the original image list($image['width'], $image['height'], $image['type']) = getimagesize($image['path']); // Check the image orientation if ($image['width'] > $image['height']) { // Landscape $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'landscape', true); } else if ($image['width'] < $image['height']) { // Portrait $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'portrait', true); } else { // Square $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'square', true); } // Iterate through the sizes to be generated foreach ($image_sizes as $size_name => $size) { // TODO: Check if an image in the requested dimensions allready exists. // Create an instance of WP_Image_Editor for the original image $new_image = wp_get_image_editor($image['path']); // Check if there is an error if (is_wp_error($new_image)) { continue; } // Resize the image $new_image->resize($size['width'], $size['height'], $size['crop']); // Save new image and store new meta data in variable $new_image_meta = $new_image->save(); // Reflect back new metadata $meta['sizes'][$size_name]['file'] = $new_image_meta['file']; $meta['sizes'][$size_name]['width'] = $new_image_meta['width']; $meta['sizes'][$size_name]['height'] = $new_image_meta['height']; $meta['sizes'][$size_name]['mime-type'] = $new_image_meta['mime-type']; } return $meta; } add_filter('wp_generate_attachment_metadata', 'r21_create_custom_image_sizes', 10, 1); /** * Deletes images, generated by r21_create_custom_image_sizes(). Use the delete_attachment hook! */ function r21_delete_custom_image_size_files($post_id) { $meta = wp_get_attachment_metadata($post_id); foreach ($meta['sizes'] as $size) { // TODO: Add support for wp_delete_file hook here @ unlink(path_join(r21_get_attachment_path_by('meta', $meta), $size['file'])); } } add_action('delete_attachment', 'r21_delete_custom_image_size_files'); не // ========================== // Custom Image Size Handling // ========================== /** * Removes default and plugin generated image sizes. * This is optional! */ function r21_remove_image_sizes($sizes) { unset($sizes['thumbnail']); unset($sizes['medium']); unset($sizes['large']); return $sizes; } add_filter('intermediate_image_sizes', 'r21_remove_image_sizes'); add_filter('intermediate_image_sizes_advanced', 'r21_remove_image_sizes'); /** * Generate a handle for thumbnail regeneration tools. * The custom images will always be regenerated after one of * the site wide image sizes have been regenerated. * The problem here is, that if there are no site wide image sizes * defined, you can not regenerate any custom size images. * To avoid this we create a 1x1 px image that works as handle, if there * are no other imge sizes. */ add_image_size( 'cstm-img-regeneration-handle' , 1, 1, array( 'left', 'top' )); /** * Delete unneeded generated images and their metadata. * Also deletes images, generated in the filter, this is why * this function has to be used before the image generation function. * * @param array $attachment_meta * @return array */ function r21_remove_old_image_sizes($attachment_meta) { foreach ($attachment_meta['sizes'] as $size_name => $size_data) { // Ceck if image size is currently an active intermediate image size if (array_key_exists($size_name, get_intermediate_image_sizes())) { continue; } // Delete file @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$size_name]['file'])); // Delete metadata unset($attachment_meta['sizes'][$size_name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_old_image_sizes', 10, 1); /** * Removes the the custom image regneration handle image, if existing. * * @return array Returns the metadata, without the handle image entry. */ function r21_remove_regeneration_hook_image($attachment_meta) { $name = 'cstm-img-regeneration-handle'; // Check if image exists if (array_key_exists($name, $attachment_meta['sizes'])) { // Delete Image File @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$name]['file'])); // Delete Image Metadata unset($attachment_meta['sizes'][$name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_regeneration_hook_image', 10, 1); /** * Generates custom image sizes, depending on the image orientation. Use the wp_generate_attachment_metadata hook! */ function r21_create_custom_image_sizes($meta) { // Initialize variables global $r21_image_sizes; $image_sizes = ''; // Generate the full file path for the image $image['path'] = path_join(wp_upload_dir()['basedir'], $meta['file']); // Get the dimensions of the original image list($image['width'], $image['height'], $image['type']) = getimagesize($image['path']); // Check the image orientation if ($image['width'] > $image['height']) { // Landscape $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'landscape', true); } else if ($image['width'] < $image['height']) { // Portrait $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'portrait', true); } else { // Square $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'square', true); } // Iterate through the sizes to be generated foreach ($image_sizes as $size_name => $size) { // TODO: Check if an image in the requested dimensions allready exists. // Create an instance of WP_Image_Editor for the original image $new_image = wp_get_image_editor($image['path']); // Check if there is an error if (is_wp_error($new_image)) { continue; } // Resize the image $new_image->resize($size['width'], $size['height'], $size['crop']); // Save new image and store new meta data in variable $new_image_meta = $new_image->save(); // Reflect back new metadata $meta['sizes'][$size_name]['file'] = $new_image_meta['file']; $meta['sizes'][$size_name]['width'] = $new_image_meta['width']; $meta['sizes'][$size_name]['height'] = $new_image_meta['height']; $meta['sizes'][$size_name]['mime-type'] = $new_image_meta['mime-type']; } return $meta; } add_filter('wp_generate_attachment_metadata', 'r21_create_custom_image_sizes', 10, 1); /** * Deletes images, generated by r21_create_custom_image_sizes(). Use the delete_attachment hook! */ function r21_delete_custom_image_size_files($post_id) { $meta = wp_get_attachment_metadata($post_id); foreach ($meta['sizes'] as $size) { // TODO: Add support for wp_delete_file hook here @ unlink(path_join(r21_get_attachment_path_by('meta', $meta), $size['file'])); } } add_action('delete_attachment', 'r21_delete_custom_image_size_files'); не // ========================== // Custom Image Size Handling // ========================== /** * Removes default and plugin generated image sizes. * This is optional! */ function r21_remove_image_sizes($sizes) { unset($sizes['thumbnail']); unset($sizes['medium']); unset($sizes['large']); return $sizes; } add_filter('intermediate_image_sizes', 'r21_remove_image_sizes'); add_filter('intermediate_image_sizes_advanced', 'r21_remove_image_sizes'); /** * Generate a handle for thumbnail regeneration tools. * The custom images will always be regenerated after one of * the site wide image sizes have been regenerated. * The problem here is, that if there are no site wide image sizes * defined, you can not regenerate any custom size images. * To avoid this we create a 1x1 px image that works as handle, if there * are no other imge sizes. */ add_image_size( 'cstm-img-regeneration-handle' , 1, 1, array( 'left', 'top' )); /** * Delete unneeded generated images and their metadata. * Also deletes images, generated in the filter, this is why * this function has to be used before the image generation function. * * @param array $attachment_meta * @return array */ function r21_remove_old_image_sizes($attachment_meta) { foreach ($attachment_meta['sizes'] as $size_name => $size_data) { // Ceck if image size is currently an active intermediate image size if (array_key_exists($size_name, get_intermediate_image_sizes())) { continue; } // Delete file @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$size_name]['file'])); // Delete metadata unset($attachment_meta['sizes'][$size_name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_old_image_sizes', 10, 1); /** * Removes the the custom image regneration handle image, if existing. * * @return array Returns the metadata, without the handle image entry. */ function r21_remove_regeneration_hook_image($attachment_meta) { $name = 'cstm-img-regeneration-handle'; // Check if image exists if (array_key_exists($name, $attachment_meta['sizes'])) { // Delete Image File @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$name]['file'])); // Delete Image Metadata unset($attachment_meta['sizes'][$name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_regeneration_hook_image', 10, 1); /** * Generates custom image sizes, depending on the image orientation. Use the wp_generate_attachment_metadata hook! */ function r21_create_custom_image_sizes($meta) { // Initialize variables global $r21_image_sizes; $image_sizes = ''; // Generate the full file path for the image $image['path'] = path_join(wp_upload_dir()['basedir'], $meta['file']); // Get the dimensions of the original image list($image['width'], $image['height'], $image['type']) = getimagesize($image['path']); // Check the image orientation if ($image['width'] > $image['height']) { // Landscape $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'landscape', true); } else if ($image['width'] < $image['height']) { // Portrait $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'portrait', true); } else { // Square $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'square', true); } // Iterate through the sizes to be generated foreach ($image_sizes as $size_name => $size) { // TODO: Check if an image in the requested dimensions allready exists. // Create an instance of WP_Image_Editor for the original image $new_image = wp_get_image_editor($image['path']); // Check if there is an error if (is_wp_error($new_image)) { continue; } // Resize the image $new_image->resize($size['width'], $size['height'], $size['crop']); // Save new image and store new meta data in variable $new_image_meta = $new_image->save(); // Reflect back new metadata $meta['sizes'][$size_name]['file'] = $new_image_meta['file']; $meta['sizes'][$size_name]['width'] = $new_image_meta['width']; $meta['sizes'][$size_name]['height'] = $new_image_meta['height']; $meta['sizes'][$size_name]['mime-type'] = $new_image_meta['mime-type']; } return $meta; } add_filter('wp_generate_attachment_metadata', 'r21_create_custom_image_sizes', 10, 1); /** * Deletes images, generated by r21_create_custom_image_sizes(). Use the delete_attachment hook! */ function r21_delete_custom_image_size_files($post_id) { $meta = wp_get_attachment_metadata($post_id); foreach ($meta['sizes'] as $size) { // TODO: Add support for wp_delete_file hook here @ unlink(path_join(r21_get_attachment_path_by('meta', $meta), $size['file'])); } } add_action('delete_attachment', 'r21_delete_custom_image_size_files'); не // ========================== // Custom Image Size Handling // ========================== /** * Removes default and plugin generated image sizes. * This is optional! */ function r21_remove_image_sizes($sizes) { unset($sizes['thumbnail']); unset($sizes['medium']); unset($sizes['large']); return $sizes; } add_filter('intermediate_image_sizes', 'r21_remove_image_sizes'); add_filter('intermediate_image_sizes_advanced', 'r21_remove_image_sizes'); /** * Generate a handle for thumbnail regeneration tools. * The custom images will always be regenerated after one of * the site wide image sizes have been regenerated. * The problem here is, that if there are no site wide image sizes * defined, you can not regenerate any custom size images. * To avoid this we create a 1x1 px image that works as handle, if there * are no other imge sizes. */ add_image_size( 'cstm-img-regeneration-handle' , 1, 1, array( 'left', 'top' )); /** * Delete unneeded generated images and their metadata. * Also deletes images, generated in the filter, this is why * this function has to be used before the image generation function. * * @param array $attachment_meta * @return array */ function r21_remove_old_image_sizes($attachment_meta) { foreach ($attachment_meta['sizes'] as $size_name => $size_data) { // Ceck if image size is currently an active intermediate image size if (array_key_exists($size_name, get_intermediate_image_sizes())) { continue; } // Delete file @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$size_name]['file'])); // Delete metadata unset($attachment_meta['sizes'][$size_name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_old_image_sizes', 10, 1); /** * Removes the the custom image regneration handle image, if existing. * * @return array Returns the metadata, without the handle image entry. */ function r21_remove_regeneration_hook_image($attachment_meta) { $name = 'cstm-img-regeneration-handle'; // Check if image exists if (array_key_exists($name, $attachment_meta['sizes'])) { // Delete Image File @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$name]['file'])); // Delete Image Metadata unset($attachment_meta['sizes'][$name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_regeneration_hook_image', 10, 1); /** * Generates custom image sizes, depending on the image orientation. Use the wp_generate_attachment_metadata hook! */ function r21_create_custom_image_sizes($meta) { // Initialize variables global $r21_image_sizes; $image_sizes = ''; // Generate the full file path for the image $image['path'] = path_join(wp_upload_dir()['basedir'], $meta['file']); // Get the dimensions of the original image list($image['width'], $image['height'], $image['type']) = getimagesize($image['path']); // Check the image orientation if ($image['width'] > $image['height']) { // Landscape $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'landscape', true); } else if ($image['width'] < $image['height']) { // Portrait $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'portrait', true); } else { // Square $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'square', true); } // Iterate through the sizes to be generated foreach ($image_sizes as $size_name => $size) { // TODO: Check if an image in the requested dimensions allready exists. // Create an instance of WP_Image_Editor for the original image $new_image = wp_get_image_editor($image['path']); // Check if there is an error if (is_wp_error($new_image)) { continue; } // Resize the image $new_image->resize($size['width'], $size['height'], $size['crop']); // Save new image and store new meta data in variable $new_image_meta = $new_image->save(); // Reflect back new metadata $meta['sizes'][$size_name]['file'] = $new_image_meta['file']; $meta['sizes'][$size_name]['width'] = $new_image_meta['width']; $meta['sizes'][$size_name]['height'] = $new_image_meta['height']; $meta['sizes'][$size_name]['mime-type'] = $new_image_meta['mime-type']; } return $meta; } add_filter('wp_generate_attachment_metadata', 'r21_create_custom_image_sizes', 10, 1); /** * Deletes images, generated by r21_create_custom_image_sizes(). Use the delete_attachment hook! */ function r21_delete_custom_image_size_files($post_id) { $meta = wp_get_attachment_metadata($post_id); foreach ($meta['sizes'] as $size) { // TODO: Add support for wp_delete_file hook here @ unlink(path_join(r21_get_attachment_path_by('meta', $meta), $size['file'])); } } add_action('delete_attachment', 'r21_delete_custom_image_size_files'); не // ========================== // Custom Image Size Handling // ========================== /** * Removes default and plugin generated image sizes. * This is optional! */ function r21_remove_image_sizes($sizes) { unset($sizes['thumbnail']); unset($sizes['medium']); unset($sizes['large']); return $sizes; } add_filter('intermediate_image_sizes', 'r21_remove_image_sizes'); add_filter('intermediate_image_sizes_advanced', 'r21_remove_image_sizes'); /** * Generate a handle for thumbnail regeneration tools. * The custom images will always be regenerated after one of * the site wide image sizes have been regenerated. * The problem here is, that if there are no site wide image sizes * defined, you can not regenerate any custom size images. * To avoid this we create a 1x1 px image that works as handle, if there * are no other imge sizes. */ add_image_size( 'cstm-img-regeneration-handle' , 1, 1, array( 'left', 'top' )); /** * Delete unneeded generated images and their metadata. * Also deletes images, generated in the filter, this is why * this function has to be used before the image generation function. * * @param array $attachment_meta * @return array */ function r21_remove_old_image_sizes($attachment_meta) { foreach ($attachment_meta['sizes'] as $size_name => $size_data) { // Ceck if image size is currently an active intermediate image size if (array_key_exists($size_name, get_intermediate_image_sizes())) { continue; } // Delete file @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$size_name]['file'])); // Delete metadata unset($attachment_meta['sizes'][$size_name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_old_image_sizes', 10, 1); /** * Removes the the custom image regneration handle image, if existing. * * @return array Returns the metadata, without the handle image entry. */ function r21_remove_regeneration_hook_image($attachment_meta) { $name = 'cstm-img-regeneration-handle'; // Check if image exists if (array_key_exists($name, $attachment_meta['sizes'])) { // Delete Image File @ unlink(path_join(r21_get_attachment_path_by('meta', $attachment_meta), $attachment_meta['sizes'][$name]['file'])); // Delete Image Metadata unset($attachment_meta['sizes'][$name]); } return $attachment_meta; } add_filter('wp_generate_attachment_metadata', 'r21_remove_regeneration_hook_image', 10, 1); /** * Generates custom image sizes, depending on the image orientation. Use the wp_generate_attachment_metadata hook! */ function r21_create_custom_image_sizes($meta) { // Initialize variables global $r21_image_sizes; $image_sizes = ''; // Generate the full file path for the image $image['path'] = path_join(wp_upload_dir()['basedir'], $meta['file']); // Get the dimensions of the original image list($image['width'], $image['height'], $image['type']) = getimagesize($image['path']); // Check the image orientation if ($image['width'] > $image['height']) { // Landscape $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'landscape', true); } else if ($image['width'] < $image['height']) { // Portrait $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'portrait', true); } else { // Square $image_sizes = r21_filter_custom_image_sizes($r21_image_sizes, 'square', true); } // Iterate through the sizes to be generated foreach ($image_sizes as $size_name => $size) { // TODO: Check if an image in the requested dimensions allready exists. // Create an instance of WP_Image_Editor for the original image $new_image = wp_get_image_editor($image['path']); // Check if there is an error if (is_wp_error($new_image)) { continue; } // Resize the image $new_image->resize($size['width'], $size['height'], $size['crop']); // Save new image and store new meta data in variable $new_image_meta = $new_image->save(); // Reflect back new metadata $meta['sizes'][$size_name]['file'] = $new_image_meta['file']; $meta['sizes'][$size_name]['width'] = $new_image_meta['width']; $meta['sizes'][$size_name]['height'] = $new_image_meta['height']; $meta['sizes'][$size_name]['mime-type'] = $new_image_meta['mime-type']; } return $meta; } add_filter('wp_generate_attachment_metadata', 'r21_create_custom_image_sizes', 10, 1); /** * Deletes images, generated by r21_create_custom_image_sizes(). Use the delete_attachment hook! */ function r21_delete_custom_image_size_files($post_id) { $meta = wp_get_attachment_metadata($post_id); foreach ($meta['sizes'] as $size) { // TODO: Add support for wp_delete_file hook here @ unlink(path_join(r21_get_attachment_path_by('meta', $meta), $size['file'])); } } add_action('delete_attachment', 'r21_delete_custom_image_size_files');