Как сделать обрезку изображения add_image_size() сверху?

24 июн. 2011 г., 12:11:17
Просмотры: 18.2K
Голосов: 21

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

В настоящее время функция add_image_size() обрезает изображение от центра. Не всегда красиво!!

0
Все ответы на вопрос 5
1
19

В WordPress Codex есть ответ, он приведен ниже.

Установка размера изображения путем обрезки и определения позиции обрезки:

add_image_size( 'custom-size', 220, 220, array( 'left', 'top' ) ); // Жесткая обрезка слева сверху

При установке позиции обрезки первое значение в массиве — это позиция обрезки по оси X, второе — по оси Y.

x_crop_position принимает значения 'left', 'center' или 'right'. y_crop_position принимает 'top', 'center' или 'bottom'. По умолчанию, при использовании режима жесткой обрезки, эти значения устанавливаются в 'center'.

Также в Codex есть ссылка на страницу, где показано, как работают позиции обрезки.

http://havecamerawilltravel.com/photographer/wordpress-thumbnail-crop

4 февр. 2015 г. 17:29:43
Комментарии

Это потрясающе, должно быть принятым ответом, я считаю!

Dalton Rooney Dalton Rooney
8 нояб. 2015 г. 22:57:06
5
13

Промежуточная генерация изображений крайне ограничена. Функция image_resize() остается близкой к коду и полностью лишена хуков.

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

Мне это нужно для работы, так что позже, возможно, смогу поделиться кодом.

Итак, вот грубый, но рабочий пример. Обратите внимание, что настройка обрезки таким способом требует понимания функции imagecopyresampled().

add_filter('wp_generate_attachment_metadata', 'custom_crop');

function custom_crop($metadata) {

    $uploads = wp_upload_dir();
    $file = path_join( $uploads['basedir'], $metadata['file'] ); // оригинальный файл изображения
    list( $year, $month ) = explode( '/', $metadata['file'] );
    $target = path_join( $uploads['basedir'], "{$year}/{$month}/".$metadata['sizes']['medium']['file'] ); // файл промежуточного размера
    $image = imagecreatefromjpeg($file); // ресурс оригинального изображения
    $image_target = wp_imagecreatetruecolor( 44, 44 ); // пустое изображение для заполнения
    imagecopyresampled($image_target, $image, 0, 0, 25, 15, 44, 44, 170, 170); // обрезка оригинала
    imagejpeg($image_target, $target, apply_filters( 'jpeg_quality', 90, 'image_resize' )); // запись обрезанного в файл

    return $metadata;
}
24 июн. 2011 г. 12:28:13
Комментарии

звучит как вмешательство в ядро!!

Mild Fuzz Mild Fuzz
24 июн. 2011 г. 12:35:36

Нет, вмешательством в ядро было бы изменение функции image_resize. Rarst имел в виду, что вам нужно подключиться к процессу изменения размеров, но создавать размеры изображений вручную.

TheDeadMedic TheDeadMedic
24 июн. 2011 г. 13:02:29

Можно спросить, работает ли это до сих пор? Я только что добавил хук в свой файл functions.php и у меня есть функции add_image_size(), но изображения по-прежнему обрезаются от центра.

cr0z3r cr0z3r
10 дек. 2011 г. 00:40:13

@cr0z3r Я не вижу причин, почему это не должно работать. Но учтите, что это лишь грубый пример proof-of-concept, а не надежный и осмысленный код.

Rarst Rarst
10 дек. 2011 г. 15:50:44

Хм, как ни странно, это не работает в моей теме - может быть потому что я запускал локально (хотя в это слабо верится)? Скоро выложу онлайн и покажу вам.

cr0z3r cr0z3r
15 дек. 2011 г. 18:32:03
2

Я разработал решение этой проблемы, не требующее изменения ядра WordPress: http://bradt.ca/archives/image-crop-position-in-wordpress/

Также я отправил патч для включения в ядро: http://core.trac.wordpress.org/ticket/19393

Добавьте себя в список Cc (копий) этого тикета, чтобы показать свою поддержку внедрения этого решения в ядро.

19 февр. 2012 г. 16:37:47
Комментарии

Решение от @Rarst тоже не изменяет файлы ядра. ;)

fuxia fuxia
19 февр. 2012 г. 17:25:36

@toscho Думаю, он не имел в виду, что другой ответ изменяет код ядра.

kaiser kaiser
20 февр. 2012 г. 17:16:48
0

Вы можете использовать плагин Thumbnail Crop Position для выбора позиции обрезки ваших миниатюр.

10 янв. 2013 г. 15:13:37
1

Альтернативное решение здесь: http://pixert.com/blog/cropping-post-featured-thumbnails-from-top-instead-of-center-in-wordpress-with-native-cropping-tool/

Просто добавьте этот код в functions.php, затем используйте плагин "Regenerate Thumbnails" (https://wordpress.org/plugins/regenerate-thumbnails/):

function px_image_resize_dimensions( $payload, $orig_w, $orig_h, $dest_w, $dest_h, $crop ){

// Измените это условие, чтобы решить, нужно ли переопределять стандартные настройки для данного изображения или нет.
if( false )
return $payload;

if ( $crop ) {
// обрезаем максимально возможную часть оригинального изображения, чтобы уместить его в $dest_w x $dest_h
$aspect_ratio = $orig_w / $orig_h;
$new_w = min($dest_w, $orig_w);
$new_h = min($dest_h, $orig_h);

if ( !$new_w ) {
$new_w = intval($new_h * $aspect_ratio);
}

if ( !$new_h ) {
$new_h = intval($new_w / $aspect_ratio);
}

$size_ratio = max($new_w / $orig_w, $new_h / $orig_h);

$crop_w = round($new_w / $size_ratio);
$crop_h = round($new_h / $size_ratio);

$s_x = 0; // [[ ранее ]] ==> floor( ($orig_w - $crop_w) / 2 );
$s_y = 0; // [[ ранее ]] ==> floor( ($orig_h - $crop_h) / 2 );
} else {
// не обрезаем, просто изменяем размер, используя $dest_w x $dest_h как максимальные границы
$crop_w = $orig_w;
$crop_h = $orig_h;

$s_x = 0;
$s_y = 0;

list( $new_w, $new_h ) = wp_constrain_dimensions( $orig_w, $orig_h, $dest_w, $dest_h );
}

// если результирующее изображение будет такого же размера или больше, мы не хотим изменять его размер
if ( $new_w >= $orig_w && $new_h >= $orig_h )
return false;

// возвращаемый массив соответствует параметрам imagecopyresampled()
// int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h );

}
add_filter( 'image_resize_dimensions', 'px_image_resize_dimensions', 10, 6 );
27 апр. 2016 г. 11:36:02
Комментарии

Привет, Niente0, добро пожаловать на WPSE и спасибо за ваш ответ. Не могли бы вы отредактировать свой пост, чтобы объяснить, что делает ваш код? Сообщения на сайтах StackExchange должны содержать объяснение решения, а внешние ссылки включать только в качестве справочных материалов, а не как полные решения. Еще раз спасибо!

Tim Malone Tim Malone
27 апр. 2016 г. 12:52:08