Partage
  • Partager sur Facebook
  • Partager sur Twitter

Upload et redimensionnement d'image "à l'ancienne"

Les images ne sont pas sauvegardées

Sujet résolu
    15 octobre 2012 à 17:54:39

    Bonsoir à tous,

    Pour un site développé à l'ancienne, tournant sur PHP 5.2.17, je rencontre un souci quand je tente d'uploader les images. Non, pas une des erreurs UPLOAD_ERR_*, mais un comportement innattendu.
    Pour autant que je m'en rende compte, PHP ne mentionne aucune erreur, mais les images ne sont pas créés/déplacées sur le serveur là où je le voudrais. Si je dis créés, c'est parce que je les redimensionne à l'aide de cette classe.
    <?php
    
    /*
     * File: SimpleImage.php
     * Author: Simon Jarvis
     * Copyright: 2006 Simon Jarvis
     * Date: 08/11/06
     * Link: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * as published by the Free Software Foundation; either version 2
     * of the License, or (at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     * GNU General Public License for more details:
     * http://www.gnu.org/licenses/gpl.html
     *
     */
    
    class SimpleImage
    {
        /**
         * SimpleImage is a Singleton class
         *
         * @var SimpleImage
         */
        private static $instance;
    
        /**
         * The image file resource handled
         *
         * @var resource
         */
        private $image;
    
        /**
         * The MIME type of the image
         *
         * @var string
         */
        private $imageType;
    
        // Constructor
        /**
         * Builds a SimpleImage object
         */
        private function __construct()
        {
        }
    
        /**
         * Gets the SimpleImage object to work on given file
         *
         * @param string $fileName
         */
        public static function getInstance($fileName = null) {
            if (!isset($instance)) {
                $c = __CLASS__;
                self::$instance = new $c();
            }
            if ($fileName != null)
                self::$instance->load($fileName);
    
            return self::$instance;
        }
    
        /**
         * Loads given file
         *
         * @param string $fileName
         */
        function load($fileName)
        {
            $image_info = getimagesize($fileName);
            $this->image_type = $image_info[2];
            if ($this->image_type == IMAGETYPE_JPEG) {
                $this->image = imagecreatefromjpeg($fileName);
            } elseif ($this->image_type == IMAGETYPE_GIF) {
                $this->image = imagecreatefromgif($fileName);
            } elseif ($this->image_type == IMAGETYPE_PNG) {
                $this->image = imagecreatefrompng($fileName);
            }
        }
    
        /**
         * Saves the image
         *
         * @param string $fileName
         * @param string $imageType
         * @param number $compression
         *  (for JPEG only)
         * @param string $permissions
         */
        function save(
            $fileName,
            $imageType = IMAGETYPE_JPEG,
            $compression = 75,
            $permissions = null
        ) {
            if ($imageType == IMAGETYPE_JPEG) {
                imagejpeg($this->image, $fileName, $compression);
            } elseif ($imageType == IMAGETYPE_GIF) {
                imagegif($this->image, $fileName);
            } elseif ($imageType == IMAGETYPE_PNG) {
                imagepng($this->image, $fileName);
            }
            if ($permissions != null) {
                chmod($fileName, $permissions);
            }
        }
    
        /**
         * Displays the image with given MIME type
         *
         * @param string $imageType
         */
        function output($imageType = IMAGETYPE_JPEG)
        {
            if ($imageType == IMAGETYPE_JPEG) {
                imagejpeg($this->image);
            } elseif ($imageType == IMAGETYPE_GIF) {
                imagegif($this->image);
            } elseif ($imageType == IMAGETYPE_PNG) {
                imagepng($this->image);
            }
        }
    
        /**
         * Gets the image width
         *
         * @return number
         */
        function getWidth()
        {
            return imagesx($this->image);
        }
    
        /**
         * Gets the imag height
         *
         * @return number
         */
        function getHeight()
        {
            return imagesy($this->image);
        }
    
        /**
         * Resizes the image to given height
         *
         * @param int $height
         * @return SimpleImage
         */
        function resizeToHeight($height)
        {
            $ratio = $height / $this->getHeight();
            $width = $this->getWidth() * $ratio;
            $this->resize($width, $height);
            return $this;
        }
    
        /**
         * Resize image to given width
         *
         * @param int $width
         * @return SimpleImage
         */
        function resizeToWidth($width)
        {
            $ratio = $width / $this->getWidth();
            $height = $this->getheight() * $ratio;
            $this->resize($width, $height);
            return $this;
        }
    
        /**
         * Scales the image to given percentage
         *
         * @param number $scale
         * @return SimpleImage
         */
        function scale($scale)
        {
            $width = $this->getWidth() * $scale / 100;
            $height = $this->getheight() * $scale / 100;
            $this->resize($width, $height);
            return $this;
        }
    
        /**
         * Resizes the image to given width and height
         *
         * @param int $width
         * @param int $height
         * @return SimpleImage
         */
        function resize($width, $height)
        {
            $new_image = imagecreatetruecolor($width, $height);
            imagecopyresampled(
                $new_image,
                $this->image,
                0,
                0,
                0,
                0,
                $width,
                $height,
                $this->getWidth(),
                $this->getHeight()
            );
            $this->image = $new_image;
            return $this;
        }
    }
    


    Pour les uploader, j'ai un formulaire "standard" et script qui fonctionne sans souci sous PHP 5.4.3, que je vous fournis ici :
    <?php
    foreach ($car['files'] as $i => $picture) {
        if (!empty($picture['error'])) {
            $message = $picture['name'] . ' : '
                    . $upload_errors[$picture['error']];
            $handle = fopen(UPLOAD_ERROR_LOG, 'a+');
            fwrite(
                $handle,
                date(DATETIME_MYSQL) . ' – ' . $picture['error'] . ' '
                        . $message . "\n"
            );
            fclose($handle);
            $nbErrors++;
            $_SESSION['errors'][] = $message;
            continue;
        }
        $basename = PICTURES_SAVE_PATH . substr(
            $picture['name'],
            0,
            strrpos($picture['name'], '.')
        ) . '_h';
        $ext = substr($picture['name'], strrpos($picture['name'], '.'));
    
        $simpleImage = SimpleImage::getInstance($picture['tmp_name']);
        $simpleImage->resizeToHeight(PICTURES_BIG_MAX_HEIGHT);
        $simpleImage->save($basename . PICTURES_BIG_MAX_HEIGHT . $ext);
        $simpleImage->resizeToHeight(PICTURES_SMALL_MAX_HEIGHT);
        $simpleImage->save($basename . PICTURES_SMALL_MAX_HEIGHT . $ext);
        $car['pictures'][] = $picture['name'];
    }
    

    Mon fichier de log reste vide, mais mon dossier d'images, dont le chemin a été vérifié, le reste tout autant.
    + images/       <-- Où doivent être stockées les images
    + scripts/      <-- Où se trouve ce script
    
    ../images/      <-- Valeur de PICTURES_SAVE_PATH


    GD est bien activé chez l'hébergeur.

    J'ai vérifié les autres dossiers, ils ne contiennent pas ces images.

    Est-ce que quelqu'un verrait pourquoi les images ne sont pas, disons, là où je m'y attendrais ?

    Merci d'avance

    -
    Edité par Ymox 21 avril 2013 à 15:21:54

    • Partager sur Facebook
    • Partager sur Twitter
    OC à changerFAQ PHP • Et avant celaTutoriel WAMP • Code illisible ? Un p'tit 👍 ici@Zeste de Savoir
      15 octobre 2012 à 23:01:44

      Pour aidé au débugage:
      Il te renvois bien true lorsque la fonction imagejpeg() est appeler dans ta méthode save ?
      • Partager sur Facebook
      • Partager sur Twitter
        16 octobre 2012 à 9:27:27

        Aucune idée, mais probablement que c'est ça, bien vu.

        Malheureusement, ces fonctions image* ne retournent qu'un booléen, et non un code qui permettrait de savoir où est l'erreur/à quoi elle est due…

        Edit

        Il semblerait que je sois un peu dans ce cas. Je teste quand je le pourrai (connexion pourrie) et je reviens.
        • Partager sur Facebook
        • Partager sur Twitter
        OC à changerFAQ PHP • Et avant celaTutoriel WAMP • Code illisible ? Un p'tit 👍 ici@Zeste de Savoir
          20 octobre 2012 à 17:48:21

          Malgré la piste fournie dans le commentaire lié dans le message précédent, je n'ai toujours pas réussi à redimensionner mes images (je sais qu'elles sont uploadées comme souhaité du fait que <?php $_FILES['error'] ne contient rien d'autre que des 0).

          Est-ce que quelqu'un aurait une vague idée de comment faire ? J'avoue ne jamais avoir été confronté à un souci de ce genre.

          Je vous fournis le code actuel de ma classe
          <?php
          
          /*
           * File: SimpleImage.php
           * Author: Simon Jarvis
           * Copyright: 2006 Simon Jarvis
           * Date: 08/11/06
           * Link: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
           *
           * This program is free software; you can redistribute it and/or
           * modify it under the terms of the GNU General Public License
           * as published by the Free Software Foundation; either version 2
           * of the License, or (at your option) any later version.
           *
           * This program is distributed in the hope that it will be useful,
           * but WITHOUT ANY WARRANTY; without even the implied warranty of
           * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
           * GNU General Public License for more details:
           * http://www.gnu.org/licenses/gpl.html
           *
           * Adapted for safe mode by Ymox on 2012-10-20
           */
          
          class SimpleImage
          {
              /**
               * Whether the PHP safe mode is on
               *
               * @var boolean
               */
              private static $safe_mode = false;
              /**
               * SimpleImage is a Singleton class
               *
               * @var SimpleImage
               */
              private static $instance;
          
              /**
               * The image file resource handled
               *
               * @var resource
               */
              private $image;
          
              /**
               * The MIME type of the image
               *
               * @var string
               */
              private $imageType;
          
              /**
               * The name of the resource image.
               * This is present only for handling servers with safe mode set to on, that
               * doesn't allow to output images with image***. As we need to have an
               * existing file, we'll use move_uploaded_file or, if we're outputting
               * another copy of the resource, copy
               *
               * @var string
               */
              private $imageName;
          
              /**
               * The number of images outputted from the loaded one.
               * This is present only for handling servers with safe mode set to on, that
               * doesn't allow to output images with image***. As we need to have an
               * existing file, we'll use move_uploaded_file or, if we're outputting
               * another copy of the resource, copy
               *
               * @var int
               */
              private $number;
          
              // Constructor
              /**
               * Builds a SimpleImage object
               */
              private function __construct()
              {
                  if (ini_get('safe_mode') == 'on') {
                      self::$safe_mode = true;
                  }
              }
          
              /**
               * Gets the SimpleImage object to work on given file
               *
               * @param string $fileName
               */
              public static function getInstance($fileName = null) {
                  if (!isset($instance)) {
                      $c = __CLASS__;
                      self::$instance = new $c();
                  }
                  if ($fileName != null) {
                      self::$instance->load($fileName);
                  }
          
                  return self::$instance;
              }
          
              /**
               * Loads given file
               *
               * @param string $fileName
               */
              function load($fileName)
              {
                  $this->number = 0;
                  if (self::$safe_mode) {
                      $this->imageName = $fileName;
                  }
                  $image_info = getimagesize($fileName);
                  $this->image_type = $image_info[2];
                  switch ($this->image_type) {
                      case IMAGETYPE_JPEG:
                          $this->image = imagecreatefromjpeg($fileName);
                          break;
                      case IMAGETYPE_GIF:
                          $this->image = imagecreatefromgif($fileName);
                          break;
                      case IMAGETYPE_PNG:
                          $this->image = imagecreatefrompng($fileName);
                          break;
                  }
              }
          
              /**
               * Saves the image
               *
               * @param string $fileName
               * @param string $imageType
               * @param number $compression
               *  (for JPEG only)
               * @param string $permissions
               * @return 
               */
              function save(
                  $fileName,
                  $imageType = IMAGETYPE_JPEG,
                  $compression = 75,
                  $permissions = null
              ) {
                  $result = 0;
                  $temp = false;
                  if (self::$safe_mode) {
                      if ($this->number == 0) {
                          move_uploaded_file($this->imageName, $fileName);
                          $this->imageName = $fileName;
                      } else {
                          copy($this->fileName, $fileName);
                      }
                  }
                  switch ($imageType) {
                      case IMAGETYPE_JPEG:
                          $temp = imagejpeg($this->image, $fileName, $compression);
                          break;
                      case IMAGETYPE_GIF:
                          $temp = imagegif($this->image, $fileName);
                          break;
                      case IMAGETYPE_PNG:
                          $temp = imagepng($this->image, $fileName);
                          break;
                  }
                  if ($temp) {
                      $result = $result & 1;
                  }
                  if ($permissions != null) {
                      $result = $result & (chmod($fileName, $permissions) ? 0 : 2);
                  }
                  return $result;
              }
          
              /**
               * Displays the image with given MIME type
               *
               * @param string $imageType
               */
              function output($imageType = IMAGETYPE_JPEG)
              {
                  $result = false;
                  switch ($imageType) {
                      case IMAGETYPE_JPEG:
                          $result = imagejpeg($this->image);
                          break;
                      case IMAGETYPE_GIF:
                          $result = imagegif($this->image);
                          break;
                      case IMAGETYPE_PNG:
                          $result = imagepng($this->image);
                          break;
                  }
                  return $result;
              }
          
              /**
               * Gets the image width
               *
               * @return number
               */
              function getWidth()
              {
                  return imagesx($this->image);
              }
          
              /**
               * Gets the imag height
               *
               * @return number
               */
              function getHeight()
              {
                  return imagesy($this->image);
              }
          
              /**
               * Resizes the image to given height
               *
               * @param int $height
               * @return SimpleImage
               */
              function resizeToHeight($height)
              {
                  $ratio = $height / $this->getHeight();
                  $width = $this->getWidth() * $ratio;
                  $this->resize($width, $height);
                  return $this;
              }
          
              /**
               * Resize image to given width
               *
               * @param int $width
               * @return SimpleImage
               */
              function resizeToWidth($width)
              {
                  $ratio = $width / $this->getWidth();
                  $height = $this->getheight() * $ratio;
                  $this->resize($width, $height);
                  return $this;
              }
          
              /**
               * Scales the image to given percentage
               *
               * @param number $scale
               * @return SimpleImage
               */
              function scale($scale)
              {
                  $width = $this->getWidth() * $scale / 100;
                  $height = $this->getheight() * $scale / 100;
                  $this->resize($width, $height);
                  return $this;
              }
          
              /**
               * Resizes the image to given width and height
               *
               * @param int $width
               * @param int $height
               * @return SimpleImage
               */
              function resize($width, $height)
              {
                  $new_image = imagecreatetruecolor($width, $height);
                  imagecopyresampled(
                      $new_image,
                      $this->image,
                      0,
                      0,
                      0,
                      0,
                      $width,
                      $height,
                      $this->getWidth(),
                      $this->getHeight()
                  );
                  $this->image = $new_image;
                  return $this;
              }
          }
          
          • Partager sur Facebook
          • Partager sur Twitter
          OC à changerFAQ PHP • Et avant celaTutoriel WAMP • Code illisible ? Un p'tit 👍 ici@Zeste de Savoir
            22 octobre 2012 à 7:17:51

            Aucune idée si il y a un message en cas de false pour imagejpeg() sa m'est jamais arrivé peut-être disponible avec error_get_last() si tu es chanceux.

            Regarde si il y aurais pas moyen d'utiliser ta méthode output + tamporisation de sortie + file_put_contents() pour testé.

            Sinon c'est sur que l'idéal serai de trouvé comment désactivé le safe mode(si l'hébergeur le permet).
            • Partager sur Facebook
            • Partager sur Twitter
              22 octobre 2012 à 14:48:12

              Citation : Belzebuth119

              Aucune idée si il y a un message en cas de false pour imagejpeg() sa m'est jamais arrivé peut-être disponible avec error_get_last() si tu es chanceux.

              Merci pour la fonction. Malheureusement, elle ne rencontre pas d'erreur dans son fonctionnement si ce n'est un cas précis qui a été prévu, et retourne false, donc je vais essayer, mais je t'avouerai douter de ce que j'arrive à en tirer quelque chose.

              Citation : Belzebuth119

              Regarde si il y aurais pas moyen d'utiliser ta méthode output + tamporisation de sortie + file_put_contents() pour testé.

              Mmm, je n'y avais effectivement pas pensé. Le seul truc est que je ne sais pas actuellement comment bufferiser la sortie, pour la canaliser vers un fichier, autrement qu'avec les différents paramètres de la fonction. Je vais creuser un peu.

              Citation : Belzebuth119

              Sinon c'est sur que l'idéal serai de trouvé comment désactivé le safe mode(si l'hébergeur le permet).

              On est d'accord, mais malheureusement ce n'est pas possible. J'ai essayé diverses syntaxes adaptées de celles proposées ici (je n'ai pas mis le <VirtualHost>, quand-même), mais apparemment je ne peux pas surcharger la configuration du serveur.
              • Partager sur Facebook
              • Partager sur Twitter
              OC à changerFAQ PHP • Et avant celaTutoriel WAMP • Code illisible ? Un p'tit 👍 ici@Zeste de Savoir
                23 octobre 2012 à 1:17:22

                Pour la tamporisation de sortie quelque chose du genre devrait faire le travail pour testé:
                <?php
                    /**
                     * Saves the image
                     *
                     * @param string $fileName
                     * @param string $imageType
                     * @param number $compression
                     *  (for JPEG only)
                     * @param string $permissions
                     * @return 
                     */
                    function saveByFileContent(
                        $fileName,
                        $imageType = IMAGETYPE_JPEG,
                        $compression = 75,
                        $permissions = null
                    ) {
                        $result = 0;
                        $temp = false;
                        if (self::$safe_mode) {
                            if ($this->number == 0) {
                                move_uploaded_file($this->imageName, $fileName);
                                $this->imageName = $fileName;
                            } else {
                                copy($this->fileName, $fileName);
                            }
                        }
                		
                	ob_start();
                	$this -> output($imageType, $compression);		
                		
                        if (file_put_contents($fileName, ob_get_contents())) {
                            $result = $result & 1;
                        }
                		
                	ob_end_clean();
                		
                        if ($permissions != null) {
                            $result = $result & (chmod($fileName, $permissions) ? 0 : 2);
                        }
                        return $result;
                    }
                
                    /**
                     * Displays the image with given MIME type
                     *
                     * @param string $imageType
                     */
                    function output($imageType = IMAGETYPE_JPEG, $compression = 75)
                    {
                        $result = false;
                        switch ($imageType) {
                            case IMAGETYPE_JPEG:
                                $result = imagejpeg($this->image, null, $compression);
                                break;
                            case IMAGETYPE_GIF:
                                $result = imagegif($this->image);
                                break;
                            case IMAGETYPE_PNG:
                                $result = imagepng($this->image);
                                break;
                        }
                        return $result;
                    }
                
                • Partager sur Facebook
                • Partager sur Twitter
                  23 octobre 2012 à 11:21:32

                  Super, merci beaucoup Belzebuth119, avec ob_*, ça fonctionne.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  OC à changerFAQ PHP • Et avant celaTutoriel WAMP • Code illisible ? Un p'tit 👍 ici@Zeste de Savoir

                  Upload et redimensionnement d'image "à l'ancienne"

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown