Redimensionnement des images et conservation des proportions

Messagepar Ayatus » Lun 15 Fév 2010, 14:46

Bonjour,

Je vous propose une petite modification sur le traitement des images permettant des conserver systématiquement leurs proportions.

Les modifications portent sur les fonctions tep_image et thumbimage auxquelles j'ai associé une nouvelle fonction, tep_aspectratio.

Dans le fichier catalog/includes/fonctions/html_output.php remplacer la fonction tep_image (ligne ~153] par :
Code: Tout sélectionner
////
// The HTML image wrapper function
  function tep_image($src, $alt = '', $width = '', $height = '', $parameters = '') {
 
    error_reporting(0);
   
    if ( (empty($src) || ($src == DIR_WS_IMAGES)) && (IMAGE_REQUIRED == 'false') ) {
      return false;
    }

    if (function_exists("gd_info")) {
      if (CONFIG_CALCULATE_IMAGE_SIZE == 'true') {
        $src=thumbimage(DIR_FS_CATALOG . $src, $width, $height, DIR_FS_CATALOG .  DIR_WS_IMAGES . 'imagecache/');
      }
    }     

    if ($image_size = tep_aspectratio($src, $width, $height)){
      $width = $image_size["width"];
      $height = $image_size["height"];
    } elseif (IMAGE_REQUIRED == 'false') {
      return false;
    }

  $image = '<img src="' . tep_output_string($src) . '" alt="' . tep_output_string($alt) . '" width="' . tep_output_string($width) . '" height="' . tep_output_string($height) . '"';
  if (tep_not_null($alt))  $image .= ' title="' . tep_output_string($alt) . '"';
  if (tep_not_null($parameters)) $image .= ' ' . $parameters;
  $image .= ' />';

  return $image;
}

remplacer la fonction thumbimage (ligne ~439] par :
Code: Tout sélectionner
// -- automatix thumbnail

function thumbimage ($image, $max_width = '', $max_height = '', $cachedir){
  if(!defined('JPEGQUALITY')) define('JPEGQUALITY', 95);    //définir la qualité des aperçus en JPEG
    error_reporting(0);

        /*##############################################
        #          - Thumbnail-Script v1.3 -           #
        # Generating thumbnails 'on-the-fly' with PHP  #
        #                                              #
        #  (c) by Christian Lamine, FlashDreams OHG    #
        #          http://www.flashdreams.de/          #
        #                                              #
        #      Modified by http://www.team-noehring.de #
        #      Modified by http://www.tse.at           #
        #      Modified by lars@iwer.de                #
        #      Traduction Fr : cynic- pour OsCss       #
          #      Modified by oscim                       #
          #      for oscss debug + php script            #
          #      Modified by Ayatus                      #
        #                                              #
        # This script may be freely used, distributed  #
        # and modified without any charge as long as   #
        # this copyright information is included.      #
        #                                              #
        # Any commercial selling of this script is     #
        # forbidden.                                   #
        #                                              #
        # The author is not responsible for possible   #
        # damage which may result from the application #
        # of this script, neither direct nor indirect. #
        # Use at your own risk!                        #
        ##############################################*/
 
  umask(0);
  !is_dir ($cachedir)
  ? mkdir ($cachedir, 0777)
  : system ("chmod 0777 ".$cachedir);

  !isset ($image)
      ? DIE ('Aucune image n'a été spécifiée !')
      : !file_exists($image)
            ? DIE ('Le fichier n'a pas pu être trouvé sur le serveur !')
            : false;

  $imagedata = getimagesize($image);

  $types = array (1 => "gif", "jpeg", "png");

  !$imagedata[2] || $imagedata[2] > 3
      ? DIE ('Le fichier spécifié n'est pas une image !')
      : false;

  $thumb_size = tep_aspectratio($image, $max_width, $max_height);
  $width = $thumb_size["width"];
  $height = $thumb_size["height"];

  $thumbfile = $width.'x'.$height.'_'. basename($image);
  if (file_exists ($cachedir.$thumbfile)) {
    $thumbdata = getimagesize ($cachedir.$thumbfile);
    $thumbdata[0] == $width && $thumbdata[1] == $height
    ? $iscached = true
    : $iscached = false;
    if (@filemtime($cachedir.$thumbfile) < @filemtime($image)) $iscached = false;
  }
  else  $iscached = false;


  if (!$iscached) {
    ($imagedata[0] > $width || $imagedata[1] > $height)
    ? $makethumb = true
    : $makethumb = false;
  }
  else $makethumb = false;

  if ($makethumb) {
    $image = call_user_func("imagecreatefrom".$types[$imagedata[2]], $image);
    if (function_exists("imagecreatetruecolor") && ($thumb = imagecreatetruecolor ($width, $height))){
      imagesavealpha($thumb, true);
      $trans_color = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
      imagefill($thumb, 0, 0, $trans_color);
      imagecopyresampled ($thumb, $image, 0, 0, 0, 0, $width, $height, $imagedata[0], $imagedata[1]);
    } else {
      $thumb = imagecreate ($width, $height);
      imagecopyresized ($thumb, $image, 0, 0, 0, 0, $width, $height, $imagedata[0], $imagedata[1]);
    }
    if ($types[$imagedata[2]] == "jpeg")  call_user_func("image".$types[$imagedata[2]], $thumb, $cachedir.$thumbfile, JPEGQUALITY);
    else   call_user_func("image".$types[$imagedata[2]], $thumb, $cachedir.$thumbfile);

    imagedestroy ($image);
    imagedestroy ($thumb);
    $image = DIR_WS_IMAGES . 'imagecache/' . $thumbfile;
  } else {
    $iscached
    ? $image = DIR_WS_IMAGES . 'imagecache/' . $thumbfile
    : $image = substr ($image, (strrpos (DIR_FS_CATALOG , '/'))+1);
  }
  return $image;
}

et ajouter en fin de fichier la fonction tep_aspectratio :
Code: Tout sélectionner
/**
* @author Ayatus
Redimensionnement des images en conservant leurs proportions
*/
function tep_aspectratio ($src, $max_width = '', $max_height = ''){
  error_reporting(0);
  $imagedata = getimagesize($src);

  !empty ($max_width) && preg_match ('/^[0-9]{1,}$/', $max_width, $regs)
  ? true
  : $max_width = $imagedata[0];
  !empty ($max_height) && preg_match ('/^[0-9]{1,}$/', $max_height, $regs)
  ? true
  : $max_height = $imagedata[1];
  $width=$max_width;
  $height=$max_height;

  if (empty ($max_width) && empty ($max_height)) {
    $width=$imagedata[0];
    $height=$imagedata[1];
  } elseif (!empty ($max_width) && !empty ($max_height)) {
    if ($max_width == $max_height){
      if ($imagedata[0] < $imagedata[1]){
        $width=ceil($max_width * $imagedata[0] / $imagedata[1]);
        $height=$max_width;
      } elseif ($imagedata[0] > $imagedata[1]){
        $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
      } elseif ($imagedata[0] == $imagedata[1]){
        $height=$max_width;
      }
    } elseif (($max_width * $imagedata[1] / $imagedata[0]) > $max_height){
      $width=ceil($max_height * $imagedata[0] / $imagedata[1]);
    } elseif (($max_height * $imagedata[0] / $imagedata[1]) > $max_width){
      $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
    } elseif ($imagedata[0] == $imagedata[1]){
      if ($max_width > $max_height){
        $width=$max_height;
      } elseif ($max_width < $max_height){
        $height=$max_width;
      }
    }
  } elseif (!empty ($max_width) && empty ($max_height)) {
    if ($imagedata[0] != $imagedata[1]){
      $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
    } elseif ($imagedata[0] == $imagedata[1]){
      $height=$max_width;
    }
  } elseif (empty ($max_width) && !empty ($max_height)) {
    if ($imagedata[0] != $imagedata[1]){
      $width=ceil($max_height * $imagedata[0] / $imagedata[1]);
    } elseif ($imagedata[0] == $imagedata[1]){
      $width=$max_height;
    }
  }

  if (($max_width > $imagedata[0]) || ($max_height > $imagedata[1])) {
    $width = $imagedata[0];
    $height = $imagedata[1];
  }

  $ratio= array("width"=>$width,"height"=>$height);
  return $ratio;
}

Ces modifications permettent de considérer la largeur et la hauteur dans configuration/images comme des valeurs maximums.
Vous pouvez y spécifier soit la largeur, soit la hauteur, ou les deux, ou rien du tout.
Dans ce dernier cas les images s'afficheront dans leur taille originale.
La valeur saisie doit être un entier ne commençant pas par 0.
En prime, lors de la création des vignettes, la transparence est conservée.

Je remercie Oscim dont l'aide fut précieuse.
Dernière édition par Ayatus le Lun 15 Fév 2010, 14:58, édité 1 fois.
Avatar de l’utilisateur
Ayatus
Site Admin
 
Messages: 280
Inscription: Sam 19 Avr 2008, 17:23

Messagepar oscim » Lun 15 Fév 2010, 15:25

C'est pas mal,

Peut être une optimisation de ligne suppl avec ds la function tep_aspectratio et quelques precisions quand a son utilisation

Code: Tout sélectionner
/**
* @author Ayatus
  Redimensionnement des images en conservant leurs proportions
  @param
    @a string path.src img
    @a float/empty max width en px
    @a float/empty max height en px
  @return array (width,height)
*/
function tep_aspectratio ($src, $max_width = '', $max_height = ''){
  error_reporting(0);
  $imagedata = getimagesize($src);

  !empty ($max_width) && preg_match ('/^[0-9]{1,}$/', $max_width, $regs)
  ? true
  : $max_width = $imagedata[0];
  !empty ($max_height) && preg_match ('/^[0-9]{1,}$/', $max_height, $regs)
  ? true
  : $max_height = $imagedata[1];
  $width=$max_width;
  $height=$max_height;

  if (!empty ($max_width) && !empty ($max_height)) {
    if ($max_width == $max_height){
      if ($imagedata[0] < $imagedata[1]){
        $width=ceil($max_width * $imagedata[0] / $imagedata[1]);
        $height=$max_width;
      }
      elseif ($imagedata[0] > $imagedata[1]) $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
      elseif ($imagedata[0] == $imagedata[1]) $height=$max_width;
    }
    elseif (($max_width * $imagedata[1] / $imagedata[0]) > $max_height) $width=ceil($max_height * $imagedata[0] / $imagedata[1]);
    elseif (($max_height * $imagedata[0] / $imagedata[1]) > $max_width) $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
    elseif ($imagedata[0] == $imagedata[1]){
      if ($max_width > $max_height) $width=$max_height;
      elseif ($max_width < $max_height) $height=$max_width;
    }
  }
  elseif (!empty ($max_width) && empty ($max_height)) {
    if ($imagedata[0] != $imagedata[1]) $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
    elseif ($imagedata[0] == $imagedata[1]) $height=$max_width;
  }
  elseif (empty ($max_width) && !empty ($max_height)) {
    if ($imagedata[0] != $imagedata[1]) $width=ceil($max_height * $imagedata[0] / $imagedata[1]);
    elseif ($imagedata[0] == $imagedata[1]) $width=$max_height;
  }

  if ((empty ($max_width) && empty ($max_height)) || ($max_width > $imagedata[0]) || ($max_height > $imagedata[1])) {
    $width = $imagedata[0];
    $height = $imagedata[1];
  }

  return array("width"=>$width,"height"=>$height);
}

Sorry d'en rajouter , je peut pas m'en empecher :)
Pour un web au normes du W3C, pour un web plus propre !

- Download osCSS Toutes versions
- stable osCSS 2.1.0 (help|info|new dev) Official help|wiki|Tuto for osCSS 2 | doc doxygen
- Utiliser le tracker pour suivre les évolutions et développements
- Inscrivez vos sites sur oscss pour présenter vos réalisations
Avatar de l’utilisateur
oscim
Site Admin
 
Messages: 1643
Inscription: Mar 25 Sep 2007, 11:33

Messagepar Ayatus » Lun 15 Fév 2010, 16:51

Bien vu,

Ces suggestions ont mis en évidence une carence dans les conditions.
Histoire de rectifier le tir en optimisant le tout.
Code: Tout sélectionner
/**
* @author Ayatus
  Redimensionnement des images en conservant leurs proportions
  @param
    @a string path.src img
    @a float/empty max width en px
    @a float/empty max height en px
  @return array (width,height)
*/
function tep_aspectratio ($src, $max_width = '', $max_height = ''){
  error_reporting(E_ALL);
  $imagedata = getimagesize($src);

  !empty ($max_width) && preg_match ('/^[0-9]{1,}$/', $max_width, $regs) && $max_width <= $imagedata[0]
  ? true
  : $max_width = $imagedata[0];
  !empty ($max_height) && preg_match ('/^[0-9]{1,}$/', $max_height, $regs) && $max_height <= $imagedata[1]
  ? true
  : $max_height = $imagedata[1];
  $width=$max_width;
  $height=$max_height;

  if ($max_width == $max_height){
    if ($imagedata[0] < $imagedata[1]){
      $width=ceil($max_width * $imagedata[0] / $imagedata[1]);
      $height=$max_width;
    }
    elseif ($imagedata[0] > $imagedata[1]) $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
    elseif ($imagedata[0] == $imagedata[1]) $height=$max_width;
  }
  elseif (($max_width * $imagedata[1] / $imagedata[0]) > $max_height) $width=ceil($max_height * $imagedata[0] / $imagedata[1]);
  elseif (($max_height * $imagedata[0] / $imagedata[1]) > $max_width) $height=ceil($max_width * $imagedata[1] / $imagedata[0]);
  elseif ($imagedata[0] == $imagedata[1]){
    if ($max_width > $max_height) $width=$max_height;
    elseif ($max_width < $max_height) $height=$max_width;
  }

  return array("width"=>$width,"height"=>$height);
}
Dernière édition par Ayatus le Lun 15 Fév 2010, 21:50, édité 1 fois.
Avatar de l’utilisateur
Ayatus
Site Admin
 
Messages: 280
Inscription: Sam 19 Avr 2008, 17:23

Messagepar Ayatus » Jeu 15 Avr 2010, 17:00

Je relance le sujet.
Voilà, l'ensemble est mis en place sur osCSS 1.2.2 et 2 tant coté public que coté admin.
Reste quelques points à éclaircir tel que le choix du stockage/nomage des vignettes.
Une première approche consiste à stocker les vignettes dans un sous dossier reprenant le chemin de l'image d'origine.
ex : imagecache/catalog/includes/languages/french/images/16x16_icon.gif.
La seconde approche consiste à nommer le fichier en le suffixant par la somme md5 du chemin d'origine.
ex : 150x110_COOLPIXL15.jpg_077af124c1f2e0f2d145bc72b79433ef.jpeg
Le but étant d'éviter l'écrasement d'une vignette au cas où deux images portent le même non et ce tout en préservant ce nom pour le référencement.
Avatar de l’utilisateur
Ayatus
Site Admin
 
Messages: 280
Inscription: Sam 19 Avr 2008, 17:23

Messagepar Louis_Cypher » Lun 19 Avr 2010, 13:45

Je vais peut-être avoir l'air d'un extra-terreste, mais on ne sait jamais :
Je pose donc ma question :
- et imagemagik dans tout cela ? Installé chez ton bon hébergeur qui se respecte...beaucoup plus fiable,rapide,complet qu'un script php..ne prend aucune ressources d'execution de script....1 ligne de commande pour obtenir le même résultat qu'une classe php interminable... déjà testé ?
oscss 1.2 + qpbpp + qtpro + gestion pointue des stocks + appros + export clients + export commandes sur ebp + liaison avec apisoft + module personnalisation + calcul des prix à la surface + ultra pics + import via csv + resize auto des images via imagemagik + plein d'autres trucs + intégration dans joomla
Louis_Cypher
Site Admin
 
Messages: 82
Inscription: Ven 22 Sep 2006, 18:08

Messagepar Ayatus » Lun 19 Avr 2010, 14:41

Imagemagick dans tout cela, j'y ai pensé à travers l'extension imagick uniquement pour les gif.
En revanche par convert, cela ne m'est pas venu à l'esprit.
Le principal soucis étant le path du binaire. Une approche telle que spip la propose pourrait être envisageable.
Le code proposé sur le forum n'est qu'une ébauche, le code final est visible ici ou et .
Avatar de l’utilisateur
Ayatus
Site Admin
 
Messages: 280
Inscription: Sam 19 Avr 2008, 17:23

Messagepar Louis_Cypher » Mar 20 Avr 2010, 14:06

Pour le resize, je résume l'ensemble de la classe php ainsi : (code valable chez ovh, par exemple)

exec("/usr/bin/convert convert images/ton_image -resize largeurxhauteur -strip -quality 90 -interlace line images/imagecache/ton_image");
oscss 1.2 + qpbpp + qtpro + gestion pointue des stocks + appros + export clients + export commandes sur ebp + liaison avec apisoft + module personnalisation + calcul des prix à la surface + ultra pics + import via csv + resize auto des images via imagemagik + plein d'autres trucs + intégration dans joomla
Louis_Cypher
Site Admin
 
Messages: 82
Inscription: Ven 22 Sep 2006, 18:08

Messagepar Ayatus » Mar 20 Avr 2010, 14:28

La raison première de ces modif ne concerne pas la création des vignettes mais la conservation des proportions avec ou sans vignette et la production d'une balise img indiquant toujours un width et un height.

Je tenterai tout de même d'introduire cette possibilité plus tard.

Pour la commande il faut l'ajuster en fonction du type d'image.
A quoi sert le "-strip" ?

Mes propos m'apparaissant inutilement agressif, je me suis auto-modéré. :P
Dernière édition par Ayatus le Mar 20 Avr 2010, 15:44, édité 1 fois.
Avatar de l’utilisateur
Ayatus
Site Admin
 
Messages: 280
Inscription: Sam 19 Avr 2008, 17:23

Messagepar Louis_Cypher » Mar 20 Avr 2010, 17:33

- imagemagik, par défaut, respect les proportions : il suffit juste de donner une seule taille : c'est la taille width ou height maxi, auto-détectée par le programme.

- imagemagik, par défaut, comprend les jpg, gif, png. Donc, pas d'ajustement nécessaire.

- strip : heu..paramètre inutile dans le cas présent, j'avais pas fais gaffe..

Ensuite, on peut etoffer la manip d'image avec différentes options..bordure, conversion de couleur, watermark..tout cela en rentrant 1 paramètre à chaque fois : quoiqu'il arrive, on reste dans 1 seule ligne pour manipuler son image.
Et cela fonctionne avec les images de (très) grandes tailles, ce que ne sait pas faire php sur un mutualisé, par exemple.

Je ne dis pas que la classe php est inutile ou bancale : elle se justifie chez certains hébergeurs. Mais si on peut profiter de la puissance imagemagik..pourquoi s'en passer ?
oscss 1.2 + qpbpp + qtpro + gestion pointue des stocks + appros + export clients + export commandes sur ebp + liaison avec apisoft + module personnalisation + calcul des prix à la surface + ultra pics + import via csv + resize auto des images via imagemagik + plein d'autres trucs + intégration dans joomla
Louis_Cypher
Site Admin
 
Messages: 82
Inscription: Ven 22 Sep 2006, 18:08


Retourner vers Developpement

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité

cron