Automatyczne kadrowanie obrazków w Prestashop 1.5.2

Tutoriale

Prestashop 1.5 Image Cropping - zoomcrop

Autor:

Front-end developer i freelancer, fan Star Wars i Terence'a McKenny

Automatyczne kadrowanie zdjęć towarów w Prestashop 1.5.2

Fotografia: Igor Wnuk (profil na G+)

Standardowy sposób tworzenia miniatur w Prestashop zakłada, że obrazek skalowany jest do największej możliwiej szerokości i wysokości, która mieści się w ustawionych wymiarach a pozostałe miejsce wypełniane jest białym tłem.

Wiele wzorów szablonów do Prestashop wymaga jednak odpowiedniego kadrowania zdjęć w specyficznych miejscach sklepu tak, aby zachować oryginalny zamysł projektanta.

Poniżej przedstawiamy jedno z możliwych podejść do rozwiązania tego problemu : automatyczny, globalny zoom-crop aktywowany przez nadanie obrazkowi odpowiedniej końcówki w nazwie. Algorytm zaczęrpnęliśmy ze znanego wszystkim TimThumba.

Rozwiązanie jest bardzo proste: zmodyfikujemy metodę resize() z klasy ImageManagerCore.php tak, aby sprawdzała, czy w nazwie danej wielkości obrazka (home_default, small_default etc.) występuje fraza "_btt". Jeśli tak - zamiast standardowego sposoby zmniejszania obrazków zostanie użyty zoom-crop.

Dzięki temu jedyne co pozostanie nam do zrobienia to dodanie nowej wielkości obrazka w panelu sterowania sklepem (Preferences -> Images -> Add New) z końcówką "_btt" i zregenerowanie miniatur. Następnie wystarczy już tylko odwołać się do nowo utworzonego rodzaju obrazka w swoich templatach i sprawa rozwiązana.

Zmiany obejmują 1 plik Prestashop: /overrides/classes/ImageManager.php

Skopiuj poniższy kod i nadpisz nim całą zawartość wspomnianego pliku:

(Ten sam kod znajdziesz też na Pastebin: http://pastebin.com/eg2tLztL)

<?php
                    
// Usage:
// Replace the contents of: 
// /overrides/classes/ImageManager.php
// With this document. Then just add a new image size in the Backoffice :
// Preferences -> Images -> Add New
// AND name it whatever_btt (attach '_btt' at the end of the name string)
// THEN just use this image size where you want :)
                    
// CAUTION! Check if you're using the same version of Prestashop as we do: 1.5.2
// (should work in all 1.5.xs though but we never checked :)
                    
// Good luck - Bazinga Designs
// http://www.bazingadesigns.com/en
                    
class ImageManager extends ImageManagerCore
{
                    
    /**
     * Resize, cut and optimize image
     *
     * Zoom & Croop when the destination file name
     * contains the '_timthumb' phrase
     * - Modified by www.bazingadesigns.com/en
     * (TimThumb ZoomCrop port)
     *
     * @param string $src_file Image object from $_FILE
     * @param string $dst_file Destination filename
     * @param integer $dst_width Desired width (optional)
     * @param integer $dst_height Desired height (optional)
     * @param string $file_type
     * @return boolean Operation result
     */
    public static function resize($src_file, $dst_file, $dst_width = null, $dst_height = null, $file_type = 'jpg', $force_type = false)
    {
        if (!file_exists($src_file))
            return false;
        list($src_width, $src_height, $type) = getimagesize($src_file);
                    
        // If PS_IMAGE_QUALITY is activated, the generated image will be a PNG with .jpg as a file extension.
        // This allow for higher quality and for transparency. JPG source files will also benefit from a higher quality
        // because JPG reencoding by GD, even with max quality setting, degrades the image.
        if (Configuration::get('PS_IMAGE_QUALITY') == 'png_all'
            || (Configuration::get('PS_IMAGE_QUALITY') == 'png' && $type == IMAGETYPE_PNG) && !$force_type)
            $file_type = 'png';
                            
        if (strpos($dst_file, '_btt')!==FALSE) 
            $zoomCrop = true;
        else
            $zoomCrop = false;
                    
        if (!$src_width)
            return false;
                    
        if ($zoomCrop == true) {
                    
            if (!$dst_width) $dst_width = 0;
            if (!$dst_height) $dst_height = 0;
                    
        } else {
                    
            if (!$dst_width)
                $dst_width = $src_width;
            if (!$dst_height)
                $dst_height = $src_height;
        }   
                    
                    
        $src_image = ImageManager::create($type, $src_file);
                    
        $width_diff = $dst_width / $src_width;
        $height_diff = $dst_height / $src_height;
                    
        if ($zoomCrop==true) {
                             
            if ($dst_width>0 && $dst_height<1) {
                $dst_height = floor ($src_height * ($dst_width / $src_width));
            } else if ($dst_height>0 && $dst_width<1) {
                $dst_width = floor ($src_width * ($dst_height / $src_height));
            }
                                     
            $src_x = $src_y = 0;
            $src_w = $src_width;
            $src_h = $src_height;
                                
            $cmp_x = $src_width / $dst_width;
            $cmp_y = $src_height / $dst_height;
                                
            if ($cmp_x > $cmp_y) {
                                
                $src_w = round (($src_width / $cmp_x * $cmp_y));
                $src_x = round (($src_width - ($src_width / $cmp_x * $cmp_y)) / 2);
                                
            } else if ($cmp_y > $cmp_x) {
                                
                $src_h = round (($src_height / $cmp_y * $cmp_x));
                $src_y = round (($src_height - ($src_height / $cmp_y * $cmp_x)) / 2);
                                
            }
                                            
        }
                    
        else if ($width_diff > 1 && $height_diff > 1)
        {
            $next_width = $src_width;
            $next_height = $src_height;
        }
        else
        {
            if (Configuration::get('PS_IMAGE_GENERATION_METHOD') == 2 || (!Configuration::get('PS_IMAGE_GENERATION_METHOD') && $width_diff > $height_diff))
            {
                $next_height = $dst_height;
                $next_width = round(($src_width * $next_height) / $src_height);
                $dst_width = (int)(!Configuration::get('PS_IMAGE_GENERATION_METHOD') ? $dst_width : $next_width);
            }
            else
            {
                $next_width = $dst_width;
                $next_height = round($src_height * $dst_width / $src_width);
                $dst_height = (int)(!Configuration::get('PS_IMAGE_GENERATION_METHOD') ? $dst_height : $next_height);
            }
        }
                    
        $dest_image = imagecreatetruecolor($dst_width, $dst_height);
                    
        // If image is a PNG and the output is PNG, fill with transparency. Else fill with white background.
        if ($file_type == 'png' && $type == IMAGETYPE_PNG)
        {
            imagealphablending($dest_image, false);
            imagesavealpha($dest_image, true);
            $transparent = imagecolorallocatealpha($dest_image, 255, 255, 255, 127);
            imagefilledrectangle($dest_image, 0, 0, $dst_width, $dst_height, $transparent);
        }
        else
        {
            $white = imagecolorallocate($dest_image, 255, 255, 255);
            imagefilledrectangle ($dest_image, 0, 0, $dst_width, $dst_height, $white);
        }
                    
        if ($zoomCrop==true)            
            imagecopyresampled($dest_image, $src_image, 0, 0, $src_x, $src_y, $dst_width, $dst_height, $src_w, $src_h);
        else
            imagecopyresampled($dest_image, $src_image, (int)(($dst_width - $next_width) / 2), (int)(($dst_height - $next_height) / 2), 0, 0, $next_width, $next_height, $src_width, $src_height);
                            
        return (ImageManager::write($file_type, $dest_image, $dst_file));
    }
                    
}


Jak zawsze dziękujemy za komentarze :)