Utiliser LiipImagineBundle pour redimensionner L'Image après le téléchargement?

j'utilise le LiipImagineBundle avec Symfony 2.1 et souhaite redimensionner les images téléchargées par l'utilisateur lors du téléchargement avant de les sauvegarder dans l'emplacement permanent du système de fichiers (pour supprimer les métadonnées, imposer le format jpeg, et limiter la taille du fichier). J'ai appeler une 'bande' et 'redimensionner' filtre de la manette, puis enregistrer l'image filtrée à partir d'un emplacement temporaire dans un dossier de mon choix dans le système de fichiers.

j'ai essayé d'utiliser le LiipImageBundle Contrôleur comme un service, comme indiqué dans le bundle du readme mais l'Action appelée est principalement destinée à créer une image filtrée dans le répertoire cache lorsqu'une requête est faite pour afficher l'image (l'utiliser pour filtrer pendant le téléchargement est un autre cas). J'ai essayé de le mettre en œuvre comme suit, et je l'ai fait fonctionner. J'ai d'abord déplacé le fichier du répertoire temporaire php du serveur web vers un répertoire dans le dossier web pour pouvoir appliquer le filtre. Ensuite, j'ai appliqué le filtre et supprimé (unlink ()) le fichier initial non filtré. Enfin, j'ai dû déplacer (renommer()) le fichier filtré vers l'emplacement permanent dans le système de fichiers. Il a fallu déplacer le fichier deux fois, appliquer le filtre une fois et supprimer le fichier (unlink) 1 pour que tout fonctionne. Y a-t-il une meilleure façon (ne pas exiger le déplacement intermédiaire) d'utiliser le paquet lors du téléchargement?

class MyController extends Controller
{
    public function new_imageAction(Request $request)
    {
        $uploadedFile = $request->files->get('file');
        $tmpFolderPathAbs = $this->get('kernel')->getRootDir() . '/../web/uploads/tmp/';
        $tmpImageNameNoExt = rand();
        $tmpImageName = $tmpImageNameNoExt . '.' . $fileExtension;
        $uploadedFile->move($tmpFolderPathAbs, $tmpImageName);
        $tmpImagePathRel = '/uploads/tmp/' . $tmpImageName;
        // Create the filtered image in a tmp folder:
        $this->container->get('liip_imagine.controller')->filterAction($request, $tmpImagePathRel, 'my_filter');
        unlink($tmpFolderPathAbs . $tmpImageName);
        $filteredImagePathAbs = $this->get('kernel')->getRootDir() . '/../web/uploads/cache/my_filter/uploads/tmp/' . $tmpImageNameNoExt . '.jpeg';
        $imagePath = $imageManagerResponse->headers->get('location');
        // define permanent location ($permanentImagePathAbs)...
        rename($filteredImagePathAbs, $permanentImagePathAbs);
    }
}

Mon filtre dans le dossier app/config/config.yml est comme suit:

liip_imagine:
    filter_sets:
        my_filter:
            format: jpeg
            filters:
                strip: ~
                thumbnail: { size: [1600, 1000], mode: inset }

Une question similaire a été posée pour la ImagineAvalancheBundle mais pas beaucoup de détails sont donnés. Peut-être la mise en œuvre de un autre service de l'ici liste fournie Est-ce une meilleure solution?

15
demandé sur Community 2013-02-24 04:18:22

5 réponses

voici donc un moyen de créer des vignettes lors du téléchargement avec LiipImagineBundle. L'astuce consiste à utiliser certains de leurs autres services:

    /**
     * Write a thumbnail image using the LiipImagineBundle
     * 
     * @param Document $document an Entity that represents an image in the database
     * @param string $filter the Imagine filter to use
     */
    private function writeThumbnail($document, $filter) {
        $path = $document->getWebPath();                                // domain relative path to full sized image
        $tpath = $document->getRootDir().$document->getThumbPath();     // absolute path of saved thumbnail

        $container = $this->container;                                  // the DI container
        $dataManager = $container->get('liip_imagine.data.manager');    // the data manager service
        $filterManager = $container->get('liip_imagine.filter.manager');// the filter manager service

        $image = $dataManager->find($filter, $path);                    // find the image and determine its type
        $response = $filterManager->get($this->getRequest(), $filter, $image, $path); // run the filter 
        $thumb = $response->getContent();                               // get the image from the response

        $f = fopen($tpath, 'w');                                        // create thumbnail file
        fwrite($f, $thumb);                                             // write the thumbnail
        fclose($f);                                                     // close the file
    }

cela peut aussi être fait en appelant directement les fonctions de la bibliothèque Imagine si vous n'avez aucune autre raison d'inclure le LiipImagineBundle. Je vais probablement regarder dans l'avenir, mais cela fonctionne pour mon cas et fonctionne très bien.

15
répondu Peter Wooster 2013-03-27 20:51:32

version modifiée de @Peter Wooster, et l'a rendu plus générique de sorte que si quelqu'un l'utilise sans entité D'Image, il/elle peut facilement en retirer benifet. Je donne ici deux versions, une qui peut être utilisée conservée dans la classe utilitaire ou non-controller. Et l'autre version est pour les classes de contrôleur. C'est à vous maintenant où vous le souhaitez :)

à utiliser en dehors du contrôleur, par exemple en le gardant dans les classes utilitaires

/**
 * Write a thumbnail image using the LiipImagineBundle
 * 
 * @param Document $fullSizeImgWebPath path where full size upload is stored e.g. uploads/attachments
 * @param string $thumbAbsPath full absolute path to attachment directory e.g. /var/www/project1/images/thumbs/
 * @param string $filter filter defined in config e.g. my_thumb
 * @param Object $diContainer Dependency Injection Object, if calling from controller just pass $this
 */
public function writeThumbnail($fullSizeImgWebPath, $thumbAbsPath, $filter, $diContainer) {
    $container = $diContainer; // the DI container, if keeping this function in controller just use $container = $this
    $dataManager = $container->get('liip_imagine.data.manager');    // the data manager service
    $filterManager = $container->get('liip_imagine.filter.manager'); // the filter manager service
    $image = $dataManager->find($filter, $fullSizeImgWebPath);                    // find the image and determine its type
    $response = $filterManager->applyFilter($image, $filter);

    $thumb = $response->getContent();                               // get the image from the response

    $f = fopen($thumbAbsPath, 'w');                                        // create thumbnail file
    fwrite($f, $thumb);                                             // write the thumbnail
    fclose($f);                                                     // close the file
}

à utiliser dans le contrôleur, p.ex. commu-contrôleur ou autre contrôleur.

/**
 * Write a thumbnail image using the LiipImagineBundle
 * 
 * @param Document $fullSizeImgWebPath path where full size upload is stored e.g. uploads/attachments
 * @param string $thumbAbsPath full absolute path to attachment directory e.g. /var/www/project1/images/thumbs/
 * @param string $filter filter defined in config e.g. my_thumb
 */
public function writeThumbnail($fullSizeImgWebPath, $thumbAbsPath, $filter) {
    $container = $this->container;
    $dataManager = $container->get('liip_imagine.data.manager');    // the data manager service
    $filterManager = $container->get('liip_imagine.filter.manager'); // the filter manager service
    $image = $dataManager->find($filter, $fullSizeImgWebPath);                    // find the image and determine its type
    $response = $filterManager->applyFilter($image, $filter);

    $thumb = $response->getContent();                               // get the image from the response

    $f = fopen($thumbAbsPath, 'w');                                        // create thumbnail file
    fwrite($f, $thumb);                                             // write the thumbnail
    fclose($f);                                                     // close the file
}
7
répondu Imran Zahoor 2014-09-08 18:46:23

Etant donné que je n'ai pas trouvé de meilleure solution, j'ai gardé la solution décrite dans la description de la question. Cette solution ne semble pas optimale du point de vue des performances (elle nécessite de déplacer le fichier deux fois, d'appliquer le filtre une fois, et de débloquer le fichier 1), mais elle permet d'accomplir le travail.

mise à jour:

j'ai changé mon code pour utiliser les services indiqués dans la réponse de Peter Wooster, comme montré ci-dessous (Cette solution est plus optimale que l'image filtrée est enregistrée directement à la destination finale):

class MyController extends Controller
{
    public function new_imageAction(Request $request)
    {
        $uploadedFile = $request->files->get('file');
        // ...get file extension and do other validation...
        $tmpFolderPathAbs = $this->get('kernel')->getRootDir() . '/../web/uploads/tmp/'; // folder to store unfiltered temp file
        $tmpImageNameNoExt = rand();
        $tmpImageName = $tmpImageNameNoExt . '.' . $fileExtension;
        $uploadedFile->move($tmpFolderPathAbs, $tmpImageName);
        $tmpImagePathRel = '/uploads/tmp/' . $tmpImageName;
        // Create the filtered image:
        $processedImage = $this->container->get('liip_imagine.data.manager')->find('my_filter', $tmpImagePathRel);
        $filteredImage = $this->container->get('liip_imagine.filter.manager')->get($request, 'my_filter', $processedImage, $tmpImagePathRel)->getContent();
        unlink($tmpFolderPathAbs . $tmpImageName); // eliminate unfiltered temp file.
        $permanentFolderPath = $this->get('kernel')->getRootDir() . '/../web/uploads/path_to_folder/';
        $permanentImagePath = $permanentFolderPath . 'my_image.jpeg';
        $f = fopen($permanentImagePath, 'w');
        fwrite($f, $filteredImage); 
        fclose($f);
    }
}
0
répondu RayOnAir 2013-04-03 15:09:34

j'ai écrit un paquet qui résout exactement ce problème. Alors que les VichUploaderBundle permet un téléchargement facile en utilisant les callbacks du cycle de vie D'ORM, LiipImagine fait un excellent travail au redimensionnement.

https://github.com/RSSfeed/VichImagineBundle

Voir la court readme sur la façon de l'implémenter en quelques minutes seulement.

0
répondu Dennis 2016-11-08 22:24:22
use Liip\ImagineBundle\Model\Binary;

puis utilisez le code suivant:

                // Generate a unique name for the file before saving it
                $fileName = md5(uniqid()) . '.' . $uploadedFile->guessExtension();

                $contents = file_get_contents($uploadedFile);

                $binary = new Binary(
                    $contents,
                    $uploadedFile->getMimeType(),
                    $uploadedFile->guessExtension()
                );

                $container = $this->container;
                $filterManager = $container->get('liip_imagine.filter.manager');    // the filter manager service
                $response = $filterManager->applyFilter($binary, 'my_thumb');

                $thumb = $response->getContent();                               // get the image from the response

                $f = fopen($webRootDir .'/images_dir/' . $fileName, 'w');                                        // create thumbnail file
                fwrite($f, $thumb);                                             // write the thumbnail
                fclose($f);                                                     // close the file
0
répondu Kinan 2017-07-02 10:42:54