Como faço para cortar add_image_size () a partir do topo?

20

Tenho uma série de postagens, todas com imagens em destaque, mas preciso personalizar o canto superior direito do recorte. Nesse caso, preciso que eles sejam cortados do canto superior direito, mas seria útil também saber como posicionar esse ponto.

No momento, a função add_image_size () está retirando o recorte do centro da imagem. Nem sempre é bonita !!

Fuzz leve
fonte

Respostas:

13

A geração intermediária de imagens é extremamente rígida. image_resize()mantém perto do código e não possui ganchos.

Praticamente a única opção para isso é conectar wp_generate_attachment_metadatae substituir a imagem gerada pelo WP por sua própria (que precisará de um pouco de image_resize()forquilha).

Eu preciso disso para o trabalho, para poder compartilhar algum código posteriormente.

Ok, aqui está difícil, mas trabalhando exemplo. Observe que configurar a colheita dessa maneira requer a compreensão de imagecopyresampled().

add_filter('wp_generate_attachment_metadata', 'custom_crop');

function custom_crop($metadata) {

    $uploads = wp_upload_dir();
    $file = path_join( $uploads['basedir'], $metadata['file'] ); // original image file
    list( $year, $month ) = explode( '/', $metadata['file'] );
    $target = path_join( $uploads['basedir'], "{$year}/{$month}/".$metadata['sizes']['medium']['file'] ); // intermediate size file
    $image = imagecreatefromjpeg($file); // original image resource
    $image_target = wp_imagecreatetruecolor( 44, 44 ); // blank image to fill
    imagecopyresampled($image_target, $image, 0, 0, 25, 15, 44, 44, 170, 170); // crop original
    imagejpeg($image_target, $target, apply_filters( 'jpeg_quality', 90, 'image_resize' )); // write cropped to file

    return $metadata;
}
Rarst
fonte
11
soa muito como mexer com o núcleo!
Fuzz suave
5
Não, mexer com o núcleo mudaria a image_resizefunção. Rarst estava dizendo que você precisaria se conectar ao processo de redimensionamento, mas crie manualmente os tamanhos de imagem.
TheDeadMedic
Posso perguntar se isso ainda funciona? Acabei de implementar o gancho no meu arquivo functions.php e tenho as funções add_image_size () configuradas, mas as imagens cortadas ainda são cortadas do centro.
cr0z3r
@ cr0z3r Não sei por que motivo não vai funcionar. Mas observe que este é apenas um exemplo de prova de conceito, e não um código confiável significativo.
Rarst
Estranhamente, ele não funciona no meu tema - poderia ser porque eu estava executando localmente (duvido muito)? Vou colocá-lo online e mostrá-lo em breve.
cr0z3r
13

O codex do Wordpress tem a resposta, está abaixo.

Defina o tamanho da imagem cortando a imagem e definindo uma posição de corte:

add_image_size( 'custom-size', 220, 220, array( 'left', 'top' ) ); // Hard crop left top

Ao definir uma posição de corte, o primeiro valor na matriz é a posição de corte do eixo x, o segundo é a posição de corte do eixo y.

x_crop_position aceita 'left' 'center' ou 'right'. y_crop_position aceita 'top', 'center' ou 'bottom'. Por padrão, esses valores são padronizados como 'central' ao usar o modo de corte rígido.

E também o codex faz referência a uma página que mostra como as posições de corte agem.

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

ewroman
fonte
Isso é incrível, deve ser a resposta aceita, eu acho!
Dalton
7

Eu desenvolvi uma solução para esse problema que não requer hackear o núcleo: http://bradt.ca/archives/image-crop-position-in-wordpress/

Também enviei um patch para o núcleo: http://core.trac.wordpress.org/ticket/19393

Adicione-se como um Cc no ticket para mostrar seu apoio para que ele seja adicionado ao núcleo.

Bradt
fonte
2
A solução da @ Rarst também não altera os arquivos principais. ;)
fuxia
11
@toscho Acho que ele não quis dizer que a outra resposta altera o código principal.
Kaiser
3

Você pode usar o plug-in Miniatura Posição de corte para selecionar a posição de corte de suas miniaturas.

PoseLab
fonte
0

Solução alternativa aqui: http://pixert.com/blog/cropping-post-featured-thumbnails-from-top-instead-of-center-in-wordpress-with-native-cropping-tool/

Basta adicionar esse código ao functions.php e usar o plug-in "Regenerar miniaturas" ( https://wordpress.org/plugins/regenerate-thumbnails/ ):

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

// Change this to a conditional that decides whether you want to override the defaults for this image or not.
if( false )
return $payload;

if ( $crop ) {
// crop the largest possible portion of the original image that we can size to $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; // [[ formerly ]] ==> floor( ($orig_w - $crop_w) / 2 );
$s_y = 0; // [[ formerly ]] ==> floor( ($orig_h - $crop_h) / 2 );
} else {
// don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
$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 the resulting image would be the same size or larger we don't want to resize it
if ( $new_w >= $orig_w && $new_h >= $orig_h )
return false;

// the return array matches the parameters to 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 );
Niente0
fonte
Olá Niente0, bem-vindo ao WPSE e obrigado pela sua resposta. Você se importaria de editar sua postagem para explicar o que seu código faz? As postagens nos sites StackExchange devem explicar sua solução e incluir apenas links externos como referências, não como soluções inteiras. Obrigado novamente!
Tim Malone