Come posso fare in modo che add_image_size() ritagli dall'alto?
Ho una serie di articoli, tutti con immagini in evidenza, ma ho bisogno di poter personalizzare il ritaglio dall'angolo in alto a destra. In questo caso, ho bisogno che vengano ritagliate dall'alto a destra, ma sarebbe utile sapere anche come posizionare manualmente quel punto.
Attualmente, la funzione add_image_size() sta effettuando il ritaglio dal centro dell'immagine. Non sempre il risultato è gradevole!!

Il codex di WordPress ha la risposta, è qui sotto.
Imposta la dimensione dell'immagine ritagliandola e definendo una posizione di ritaglio:
add_image_size( 'custom-size', 220, 220, array( 'left', 'top' ) ); // Ritaglio fisso in alto a sinistra
Quando si imposta una posizione di ritaglio, il primo valore nell'array è la posizione di ritaglio sull'asse x, il secondo sull'asse y.
x_crop_position accetta 'left', 'center' o 'right'. y_crop_position accetta 'top', 'center' o 'bottom'. Di default, questi valori sono impostati su 'center' quando si utilizza la modalità di ritaglio fisso.
Inoltre il codex fa riferimento a una pagina che mostra come agiscono le posizioni di ritaglio.
http://havecamerawilltravel.com/photographer/wordpress-thumbnail-crop

La generazione di immagini intermedie è estremamente rigida. La funzione image_resize()
mantiene il controllo vicino al codice e manca completamente di hook.
Praticamente l'unica opzione è agganciarsi a wp_generate_attachment_metadata
e sovrascrivere l'immagine generata da WordPress con la propria (il che richiederà un po' di fork del codice di image_resize()
).
Mi serve per lavoro, quindi potrei condividere del codice più avanti.
Ok, ecco un esempio grezzo ma funzionante. Nota che impostare il ritaglio in questo modo richiede la comprensione di imagecopyresampled()
.
add_filter('wp_generate_attachment_metadata', 'custom_crop');
function custom_crop($metadata) {
$uploads = wp_upload_dir();
$file = path_join( $uploads['basedir'], $metadata['file'] ); // file immagine originale
list( $year, $month ) = explode( '/', $metadata['file'] );
$target = path_join( $uploads['basedir'], "{$year}/{$month}/".$metadata['sizes']['medium']['file'] ); // file dimensione intermedia
$image = imagecreatefromjpeg($file); // risorsa immagine originale
$image_target = wp_imagecreatetruecolor( 44, 44 ); // immagine vuota da riempire
imagecopyresampled($image_target, $image, 0, 0, 25, 15, 44, 44, 170, 170); // ritaglia l'originale
imagejpeg($image_target, $target, apply_filters( 'jpeg_quality', 90, 'image_resize' )); // scrive l'immagine ritagliata su file
return $metadata;
}

No, intervenire sul core vorrebbe dire modificare la funzione image_resize
. Rarst stava sottolineando che dovresti agganciarti al processo di ridimensionamento, ma creare le dimensioni delle immagini manualmente da te.

Posso chiedere se funziona ancora? Ho appena implementato l'hook nel mio file functions.php e ho configurato le funzioni add_image_size(), ma le immagini ritagliate vengono ancora ritagliate partendo dal centro.

@cr0z3r Non conosco alcun motivo per cui non dovrebbe funzionare. Ma tieni presente che questo è solo un esempio approssimativo di proof-of-concept, piuttosto che un codice significativo e affidabile.

Ho sviluppato una soluzione a questo problema che non richiede modifiche al core di WordPress: http://bradt.ca/archives/image-crop-position-in-wordpress/
Ho anche inviato una patch per il core: http://core.trac.wordpress.org/ticket/19393
Aggiungiti come Cc nel ticket per mostrare il tuo supporto affinché venga aggiunto al core.

Puoi utilizzare il plugin Thumbnail Crop Position per selezionare la posizione di ritaglio delle tue miniature.

Soluzione alternativa qui: http://pixert.com/blog/cropping-post-featured-thumbnails-from-top-instead-of-center-in-wordpress-with-native-cropping-tool/
Aggiungi questo codice a functions.php, poi utilizza il plugin "Regenerate Thumbnails" (https://wordpress.org/plugins/regenerate-thumbnails/):
function px_image_resize_dimensions( $payload, $orig_w, $orig_h, $dest_w, $dest_h, $crop ){
// Modifica questa condizione per decidere quando vuoi sovrascrivere le impostazioni predefinite per questa immagine
if( false )
return $payload;
if ( $crop ) {
// Ritaglia la porzione più grande possibile dell'immagine originale che possiamo ridimensionare a $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; // [[ precedentemente ]] ==> floor( ($orig_w - $crop_w) / 2 );
$s_y = 0; // [[ precedentemente ]] ==> floor( ($orig_h - $crop_h) / 2 );
} else {
// Non ritagliare, solo ridimensiona usando $dest_w x $dest_h come box massimo
$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 );
}
// Se l'immagine risultante sarebbe della stessa dimensione o più grande, non vogliamo ridimensionarla
if ( $new_w >= $orig_w && $new_h >= $orig_h )
return false;
// L'array restituito corrisponde ai parametri di 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 );

Ciao Niente0, benvenuto su WPSE e grazie per la tua risposta. Potresti modificare il tuo post per spiegare cosa fa il tuo codice? I post sui siti StackExchange dovrebbero spiegare la soluzione proposta e includere link esterni solo come riferimenti, non come soluzioni complete. Grazie ancora!
