web-dev-qa-db-fra.com

Il existe un moyen de redimensionner les supports (images) à 50%?

Je me demande s’il est possible de réduire le nombre de fichiers téléchargés à 50% exactement.

D'après ce que je vois, avec add_image_size, vous ne pouvez spécifier qu'une largeur et une hauteur en pixels.

L'idée est de télécharger des images haute résolution pour les écrans Retina, puis de laisser Wordpress générer une taille d'image personnalisée réduite pour les écrans standard.

Le mieux serait d'appliquer ceci à la fois à l'image d'origine et à toutes les autres vignettes personnalisées générées.

Merci pour l'aide.

3
achairapart

Vous pouvez utiliser le filtre image_downsize et attraper quand WordPress veut une image réduite et non originale, et en fait une taille qui n'existe pas.

add_filter( 'image_downsize', 'wpse_60890_retina_scale', 10, 3 );

function wpse_60890_retina_scale( $value, $id, $size ) {
    if ( $size == 'wpse_60890_retina_scaled' ) {
        if ( !is_array( $imagedata = wp_get_attachment_metadata( $id ) ) )
            return false;

        $img_url          = wp_get_attachment_url( $id );
        $img_url_basename = wp_basename( $img_url );

        if ( isset( $imagedata['sizes']['wpse_60890_retina_scaled'] ) ) {
            $intermediate = $imagedata['sizes']['wpse_60890_retina_scaled'];
            $url  = str_replace($img_url_basename, $intermediate['file'], $img_url);

            return array( $url, $data['width'], $data['height'] );
        }

        $file = get_attached_file( $id );
        $image = wp_load_image( $file );

        if ( !is_resource( $image ) )
            return new WP_Error( 'error_loading_image', $image, $file );

        $size = @getimagesize( $file );
        if ( !$size )
            return new WP_Error( 'invalid_image', __('Could not read image size'), $file );

        list( $orig_w, $orig_h, $orig_type ) = $size;

        $max_w = round( $orig_w / 2 );
        $max_h = round( $orig_h / 2 );

        $resized = image_make_intermediate_size( $file, $max_w, $max_h );

        $imagedata['sizes']['wpse_60890_retina_scaled'] = $resized;

        wp_update_attachment_metadata( $id, $imagedata );

        $url = str_replace($img_url_basename, $resized['file'], $img_url);

        return array( $url, $resized['width'], $resized['height'] );
    }

    return $value;
}

Vous devez maintenant déterminer où vous avez besoin d'une taille maximale ou d'une réduction de 50%.

Par exemple vous avez

   echo 'full size:' . wp_get_attachment_image( $attachment->ID, 'full' );
   echo 'scaled by 50%: ' . wp_get_attachment_image( $attachment->ID, 'wpse_60890_retina_scaled' );
3
nvartolomei

Je ne pouvais pas utiliser la solution @nvartolomei telle quelle. Ce n'était pas fonctionnel mais c'était quand même un bon point de départ.

Voici ma solution finale:

J'ajoute 3 nouveaux image sizes en doublant les 3 tailles d'origine.

  • large_retina
  • medium_retina
  • thumbnail_retina

Ensuite, je mets filtre lorsque vous les appelez dans PHP pour remplacer with et height par leur équivalent non rétinien (puisqu'il n'est pas toujours question de diviser par 2).

  • original: src = image.jpg width = 4800 height = 4000
  • large (600x600): src = image-600x500.jpg width = 600 height = 500
  • large_retina (600x600): src = image-1200x1000.jpg width = 600 height = 500

  • original: src = image.jpg width = 900 height = 750

  • large (600x600): src = image-600x500.jpg width = 600 height = 500
  • large_retina (600x600): src = image.jpg width = 600 height = 500

function.php:

add_action( 'init', 'cjg_register_sizes' );
add_filter( 'image_downsize', 'cjg_retina_scale', 10, 3 );

function cjg_register_sizes(){
    add_image_size( 'large_retina', get_option( 'large_size_w' ) * 2 , get_option( 'large_size_h' ) * 2 );
    add_image_size( 'medium_retina', get_option( 'medium_size_w' ) * 2 , get_option( 'medium_size_h' ) * 2 );
    add_image_size( 'thumbnail_retina', get_option( 'thumbnail_size_w' ) * 2 , get_option( 'thumbnail_size_h' ) * 2 );
}

function cjg_retina_scale( $value, $id, $size ) {

    if ( $size == 'large_retina' OR $size == 'medium_retina' OR $size == 'thumbnail_retina' ) {
        if ( !is_array( $imagedata = wp_get_attachment_metadata( $id ) ) )
            return false;

        if ( $size == 'large_retina')       $regular_size = 'large';
        elseif ( $size == 'medium_retina')  $regular_size = 'medium'; 
        else                                $regular_size = 'thumbnail';

        $img_url          = wp_get_attachment_url( $id );
        $img_url_basename = wp_basename( $img_url );

        if ( isset( $imagedata['sizes'][$regular_size] ) ) {

            $width = $imagedata['sizes'][$regular_size]['width'];
            $height = $imagedata['sizes'][$regular_size]['height'];

            if ( isset( $imagedata['sizes'][$size] ) )
                $url  = str_replace($img_url_basename, $imagedata['sizes'][$size]['file'], $img_url);
            else
                $url  = $img_url;

        }else{
            $url  = $img_url;
            $width = $imagedata['width'];
            $height = $imagedata['height'];
        }

        return array( $url, $width, $height );
    }

    return $value;
}

Maintenant, vous pouvez simplement appeler vos images de cette façon

wp_get_attachment_image( $attachment->ID, 'thumbnail_retina' );
wp_get_attachment_image( $attachment->ID, 'medium_retina' );
wp_get_attachment_image( $attachment->ID, 'large_retina' );

Important: après avoir ajouté les 3 nouvelles tailles, j'ai régénéré toutes les vignettes avec le plugin regenerate-thumbnails

2
Christian