Jump to content

Recommended Posts

Подскажите как добавить watermark до ресайза, а не после?
А-то получается картинка с большим знаком.
функцию watermark'a передвигаю, вообще знак пропадает.
 
Нужно чтобы было, как на картинке 1, помогите кто разбирается...

post-12777-0-38369100-1428441273.png    post-12777-0-49596100-1428441279.png

 

 

api/image.php

<?php

/**
 * Simpla CMS
 *
 * @copyright    2011 Denis Pikusov
 * @link        http://simplacms.ru
 * @author        Denis Pikusov
 *
 */

require_once('Simpla.php');

class Image extends Simpla
{
    private    $allowed_extentions = array('png', 'gif', 'jpg', 'jpeg', 'ico');

    public function __construct()
    {        
        parent::__construct();
    }
    
    
    /**
     * Создание превью изображения
     * @param $filename файл с изображением (без пути к файлу)
     * @param max_w максимальная ширина
     * @param max_h максимальная высота
     * @return $string имя файла превью
     */
    function resize($filename)
    {
        $path_filename = "";
        list($source_file, $width , $height, $set_watermark) = $this->get_resize_params($filename);
        //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "resize(1): filename - ".$filename." sourcefile - ".$source_file."\n",FILE_APPEND);
        // Если вайл удаленный (http://), зальем его себе
        if(substr($source_file, 0, 7) == 'http://')
        {    
            
            //Если в name его нет, ищем в filename
            //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "resize: Запускаю запрос по поиску в базе\n",FILE_APPEND);
            $this->db->query('SELECT filename FROM __images WHERE name=? LIMIT 1', $source_file);
            $path_filename = $this->db->result('filename');
            if(empty($path_filename))
                {
                    //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "resize: запускаю download_image\n",FILE_APPEND);
                    // Если не получилось найти файл в name, то качаем от поставщика
                    if(!$original_file = $this->download_image($source_file))
                        {
                         //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "resize:Выхожу из скрипта\n",FILE_APPEND);
                         return false;                
                        }
                }else {
                        //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "resize(2): В filename - ".$path_filename."\n",FILE_APPEND);
                        $original_file = $path_filename;
                      }
                        //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "resize: В итоге original_file ->".$original_file."\n",FILE_APPEND);
            $resized_file = $this->add_resize_params($original_file, $width, $height, $set_watermark);            
        }    
        else
        {
            //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "resize: не пришло http\n",FILE_APPEND);
            $original_file = $source_file;
        }
        
        $resized_file = $this->add_resize_params($original_file, $width, $height, $set_watermark);            
        
    
        // Пути к папкам с картинками
        $originals_dir = $this->config->root_dir.$this->config->original_images_dir;
        $preview_dir = $this->config->root_dir.$this->config->resized_images_dir;
        
        $watermark_offet_x = $this->settings->watermark_offset_x;
        $watermark_offet_y = $this->settings->watermark_offset_y;
        
        $sharpen = min(100, $this->settings->images_sharpen)/100;
        $watermark_transparency =  1-min(100, $this->settings->watermark_transparency)/100;
    
    
        if($set_watermark && is_file($this->config->root_dir.$this->config->watermark_file))
            $watermark = $this->config->root_dir.$this->config->watermark_file;
        else
            $watermark = null;

        if(class_exists('Imagick') && $this->config->use_imagick)
            $this->image_constrain_imagick($originals_dir.$original_file, $preview_dir.$resized_file, $width, $height, $watermark, $watermark_offet_x, $watermark_offet_y, $watermark_transparency, $sharpen);
        else
            $this->image_constrain_gd($originals_dir.$original_file, $preview_dir.$resized_file, $width, $height, $watermark, $watermark_offet_x, $watermark_offet_y, $watermark_transparency);
        
        return $preview_dir.$resized_file;
    }

    public function add_resize_params($filename, $width=0, $height=0, $set_watermark=false)
    {
        if('.' != ($dirname = pathinfo($filename,  PATHINFO_DIRNAME)))
            $file = $dirname.'/'.pathinfo($filename, PATHINFO_FILENAME);
        else
            $file = pathinfo($filename, PATHINFO_FILENAME);
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
    
        if($width>0 || $height>0)
            $resized_filename = $file.'.'.($width>0?$width:'').'x'.($height>0?$height:'').($set_watermark?'w':'').'.'.$ext;
        else
            $resized_filename = $file.'.'.($set_watermark?'w.':'').$ext;
            
        return $resized_filename;
    }

    public function get_resize_params($filename)
    {
        // Определаяем параметры ресайза
        if(!preg_match('/(.+)\.([0-9]*)x([0-9]*)(w)?\.([^\.]+)$/', $filename, $matches))
            return false;
            
        $file = $matches[1];                    // имя запрашиваемого файла
        $width = $matches[2];                    // ширина будущего изображения
        $height = $matches[3];                    // высота будущего изображения
        $set_watermark = $matches[4] == 'w';    // ставить ли водяной знак
        $ext = $matches[5];                        // расширение файла
            
        return array($file.'.'.$ext, $width, $height, $set_watermark);
    }
    
    
    public function download_image($filename)
    {
        // Заливаем только есть такой файл есть в базе
        //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "download_image:запуск\n",FILE_APPEND);
        $this->db->query('SELECT 1 FROM __images WHERE filename=? LIMIT 1', $filename);
        if(!$this->db->result())
            {
             //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "download_image:Запрос не отработан\n",FILE_APPEND);
             return false;
            }
        //file_put_contents("/home/virtwww/w_sexshop_859eec2c/http/log.txt", "download_image:Запрос ОТРАБОТАН\n",FILE_APPEND);
        // Имя оригинального файла
        $basename = explode('&', pathinfo($filename, PATHINFO_BASENAME));
        $uploaded_file = array_shift($basename);
        $base = urldecode(pathinfo($uploaded_file, PATHINFO_FILENAME));
        $ext = pathinfo($uploaded_file, PATHINFO_EXTENSION);
        
        // Если такой файл существует, нужно придумать другое название
        $new_name = urldecode($uploaded_file);
            
        while(file_exists($this->config->root_dir.$this->config->original_images_dir.$new_name))
        {
            $new_base = pathinfo($new_name, PATHINFO_FILENAME);
            if(preg_match('/_([0-9]+)$/', $new_base, $parts))
                $new_name = $base.'_'.($parts[1]+1).'.'.$ext;
            else
                $new_name = $base.'_1.'.$ext;
        }
        $this->db->query('UPDATE __images SET name=? WHERE filename=?', $filename, $filename);
        $this->db->query('UPDATE __images SET filename=? WHERE filename=?', $new_name, $filename);
            
        
        // Перед долгим копированием займем это имя
        fclose(fopen($this->config->root_dir.$this->config->original_images_dir.$new_name, 'w'));
        copy($filename, $this->config->root_dir.$this->config->original_images_dir.$new_name);
        return $new_name;
    }

    public function upload_image($filename, $name)
    {
        // Имя оригинального файла
        $name = $this->correct_filename($name);
        $uploaded_file = $new_name = pathinfo($name, PATHINFO_BASENAME);
        $base = pathinfo($uploaded_file, PATHINFO_FILENAME);
        $ext = pathinfo($uploaded_file, PATHINFO_EXTENSION);
        
        if(in_array(strtolower($ext), $this->allowed_extentions))
        {            
            while(file_exists($this->config->root_dir.$this->config->original_images_dir.$new_name))
            {    
                $new_base = pathinfo($new_name, PATHINFO_FILENAME);
                if(preg_match('/_([0-9]+)$/', $new_base, $parts))
                    $new_name = $base.'_'.($parts[1]+1).'.'.$ext;
                else
                    $new_name = $base.'_1.'.$ext;
            }
            if(move_uploaded_file($filename, $this->config->root_dir.$this->config->original_images_dir.$new_name))            
                return $new_name;
        }

        return false;
    }

    
    /**
     * Создание превью средствами gd
     * @param $src_file исходный файл
     * @param $dst_file файл с результатом
     * @param max_w максимальная ширина
     * @param max_h максимальная высота
     * @return bool
     */
    private function image_constrain_gd($src_file, $dst_file, $max_w, $max_h, $watermark=null, $watermark_offet_x=0, $watermark_offet_y=0, $watermark_opacity=1)
    {
        $quality = 100;
    
        // Параметры исходного изображения
        @list($src_w, $src_h, $src_type) = array_values(getimagesize($src_file));
        $src_type = image_type_to_mime_type($src_type);    
        
        if(empty($src_w) || empty($src_h) || empty($src_type))
            return false;
    
        // Нужно ли обрезать?
        if (!$watermark && ($src_w <= $max_w) && ($src_h <= $max_h))
        {
            // Нет - просто скопируем файл
            if (!copy($src_file, $dst_file))
                return false;
            return true;
        }
                
        // Размеры превью при пропорциональном уменьшении
        @list($dst_w, $dst_h) = $this->calc_contrain_size($src_w, $src_h, $max_w, $max_h);
    
        // Читаем изображение
        switch ($src_type)
        {
        case 'image/jpeg':    
            $src_img = imageCreateFromJpeg($src_file);        
            break;
        case 'image/gif':
            $src_img = imageCreateFromGif($src_file);        
            break;
        case 'image/png':
            $src_img = imageCreateFromPng($src_file);                    
            imagealphablending($src_img, true);
            break;
        default:
            return false;
        }
        
        if(empty($src_img))
            return false;
            
        $src_colors = imagecolorstotal($src_img);
        
        // create destination image (indexed, if possible)
        if ($src_colors > 0 && $src_colors <= 256)
            $dst_img = imagecreate($dst_w, $dst_h);
        else
            $dst_img = imagecreatetruecolor($dst_w, $dst_h);
        
        if (empty($dst_img))
            return false;
    
        $transparent_index = imagecolortransparent($src_img);
        if ($transparent_index >= 0 && $transparent_index <= 128)
        {
            $t_c = imagecolorsforindex($src_img, $transparent_index);
            $transparent_index = imagecolorallocate($dst_img, $t_c['red'], $t_c['green'], $t_c['blue']);
            if ($transparent_index === false)
                return false;
            if (!imagefill($dst_img, 0, 0, $transparent_index))
                return false;
            imagecolortransparent($dst_img, $transparent_index);
        }
        // or preserve alpha transparency for png
        elseif ($src_type === 'image/png')
        {
            if (!imagealphablending($dst_img, false))
                return false;
            $transparency = imagecolorallocatealpha($dst_img, 0, 0, 0, 127);
            if (false === $transparency)
                return false;
            if (!imagefill($dst_img, 0, 0, $transparency))
                return false;
            if (!imagesavealpha($dst_img, true))
                return false;
        }        
            
        // resample the image with new sizes
        if (!imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $dst_w, $dst_h, $src_w, $src_h))
            return false;    
            
        // Watermark
        if(!empty($watermark) && is_readable($watermark))
        {    
            $overlay = imagecreatefrompng($watermark);
            
            // Get the size of overlay
            $owidth = imagesx($overlay);
            $oheight = imagesy($overlay);
            
            $watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/300, $dst_w);
            $watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/220, $dst_h);
    
            imagecopy($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);        
            //imagecopymerge($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight, $watermark_opacity*100);
            
        }    
                
            
        // recalculate quality value for png image
        if ('image/png' === $src_type)
        {
            $quality = round(($quality / 100) * 10);
            if ($quality < 1)
                $quality = 1;
            elseif ($quality > 10)
                $quality = 10;
            $quality = 10 - $quality;
        }
    
        // Сохраняем изображение
        switch ($src_type)
        {
        case 'image/jpeg':    
            return imageJpeg($dst_img, $dst_file, $quality);
        case 'image/gif':
            return imageGif($dst_img, $dst_file, $quality);
        case 'image/png':
            imagesavealpha($dst_img, true);
            return imagePng($dst_img, $dst_file, $quality);
        default:
            return false;
        }
    }
    
    /**
     * Создание превью средствами imagick
     * @param $src_file исходный файл
     * @param $dst_file файл с результатом
     * @param max_w максимальная ширина
     * @param max_h максимальная высота
     * @return bool
     */
    private function image_constrain_imagick($src_file, $dst_file, $max_w, $max_h, $watermark=null, $watermark_offet_x=0, $watermark_offet_y=0, $watermark_opacity=1, $sharpen=0.2)
    {
        $thumb = new Imagick();
        
        // Читаем изображение
        if(!$thumb->readImage($src_file))
            return false;
        
        // Размеры исходного изображения
        $src_w = $thumb->getImageWidth();
        $src_h = $thumb->getImageHeight();
        
        // Нужно ли обрезать?
        if (!$watermark && ($src_w <= $max_w) && ($src_h <= $max_h))
        {
            // Нет - просто скопируем файл
            if (!copy($src_file, $dst_file))
                return false;
            return true;
        }    
            
        // Размеры превью при пропорциональном уменьшении
        list($dst_w, $dst_h) = $this->calc_contrain_size($src_w, $src_h, $max_w, $max_h);
    
        // Уменьшаем
        $thumb->thumbnailImage($dst_w, $dst_h);
        
        // Устанавливаем водяной знак
        if($watermark && is_readable($watermark))
        {
            $overlay = new Imagick($watermark);
            //$overlay->setImageOpacity($watermark_opacity);
            //$overlay_compose = $overlay->getImageCompose();
            $overlay->evaluateImage(Imagick::EVALUATE_MULTIPLY, $watermark_opacity, Imagick::CHANNEL_ALPHA);
            
            // Get the size of overlay
            $owidth = $overlay->getImageWidth();
            $oheight = $overlay->getImageHeight();
            
            $watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/100, $dst_w);
            $watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/100, $dst_h);
            
        }
        
        
        // Анимированные gif требуют прохода по фреймам
        foreach($thumb as $frame)
        {
            // Уменьшаем
            $frame->thumbnailImage($dst_w, $dst_h);
            
            /* Set the virtual canvas to correct size */
            $frame->setImagePage($dst_w, $dst_h, 0, 0);
            
            // Наводим резкость
            if($sharpen > 0)        
                $thumb->adaptiveSharpenImage($sharpen, $sharpen);
                
            if(isset($overlay) && is_object($overlay))
            {
                // $frame->compositeImage($overlay, $overlay_compose, $watermark_x, $watermark_y, imagick::COLOR_ALPHA);
                $frame->compositeImage($overlay, imagick::COMPOSITE_OVER, $watermark_x, $watermark_y, imagick::COLOR_ALPHA);
            }
                
        }    
        
        // Убираем комменты и т.п. из картинки
        $thumb->stripImage();
        
        //        $thumb->setImageCompressionQuality(100);
        
        // Записываем картинку
        if(!$thumb->writeImages($dst_file, true))
            return false;
        
        // Уборка
        $thumb->destroy();
        if(isset($overlay) && is_object($overlay))
            $overlay->destroy();
        
        return true;
    }
    
    
    /**
     * Вычисляет размеры изображения, до которых нужно его пропорционально уменьшить, чтобы вписать в квадрат $max_w x $max_h
     * @param src_w ширина исходного изображения
     * @param src_h высота исходного изображения
     * @param max_w максимальная ширина
     * @param max_h максимальная высота
     * @return array(w, h)
     */
    function calc_contrain_size($src_w, $src_h, $max_w = 0, $max_h = 0)
    {
        if($src_w == 0 || $src_h == 0)
            return false;
            
        $dst_w = $src_w;
        $dst_h = $src_h;
    
        if($src_w > $max_w && $max_w>0)
        {
            $dst_h = $src_h * ($max_w/$src_w);
            $dst_w = $max_w;
        }
        if($dst_h > $max_h && $max_h>0)
        {
            $dst_w = $dst_w * ($max_h/$dst_h);
            $dst_h = $max_h;
        }
        return array($dst_w, $dst_h);
    }    
    
    
    private function files_identical($fn1, $fn2)
    {
        $buffer_len = 1024;
        if(!$fp1 = fopen(dirname(dirname(__FILE__)).'/'.$fn1, 'rb'))
            return FALSE;
    
        if(!$fp2 = fopen($fn2, 'rb')) {
            fclose($fp1);
            return FALSE;
        }
    
        $same = TRUE;
        while (!feof($fp1) and !feof($fp2))
            if(fread($fp1, $buffer_len) !== fread($fp2, $buffer_len)) {
                $same = FALSE;
                break;
            }
    
        if(feof($fp1) !== feof($fp2))
            $same = FALSE;
    
        fclose($fp1);
        fclose($fp2);
    
        return $same;
    }

    private function correct_filename($filename)
    {
        $ru = explode('-', "А-а-Б-б-В-в-Ґ-ґ-Г-г-Д-д-Е-е-Ё-ё-Є-є-Ж-ж-З-з-И-и-І-і-Ї-ї-Й-й-К-к-Л-л-М-м-Н-н-О-о-П-п-Р-р-С-с-Т-т-У-у-Ф-ф-Х-х-Ц-ц-Ч-ч-Ш-ш-Щ-щ-Ъ-ъ-Ы-ы-Ь-ь-Э-э-Ю-ю-Я-я");
        $en = explode('-', "A-a-B-b-V-v-G-g-G-g-D-d-E-e-E-e-E-e-ZH-zh-Z-z-I-i-I-i-I-i-J-j-K-k-L-l-M-m-N-n-O-o-P-p-R-r-S-s-T-t-U-u-F-f-H-h-TS-ts-CH-ch-SH-sh-SCH-sch---Y-y---E-e-YU-yu-YA-ya");

         $res = str_replace($ru, $en, $filename);
        $res = preg_replace("/[\s]+/ui", '-', $res);
        $res = preg_replace("/[^a-zA-Z0-9\.\-\_]+/ui", '', $res);
         $res = strtolower($res);
        return $res;  
    }
    
}
 
Edited by Amarous
Link to post
Share on other sites

Нужно чтоб на большой картинке был большой варемарк, на маленькой - маленький.

Уменьшать ватемарк не нужно, нужно его наложить перед уменьшением картинки.

Link to post
Share on other sites

Совсем просто вряд ли выйдет.

Надо разбираться в приведенном Вами листинге и вносить изменения немалые.

Собственно наложить водяной знак можно почти одной строкой кода, но надо это делать в момент перед созданием первого резайза, а стандартными средствами отловить этот момент, кажется, нельзя. И тут хлопоты возникают.

Link to post
Share on other sites
  • 10 months later...

значит, столкнулся тоже с этой проблемой, вот мое решение:
 

для начала у меня не хотела заводится прозрозрачность водяного знака, для этого я изменил библиотеку работы с изображениями с imagegick на gd

[images]
;Использовать imagemagick для обработки изображений (вместо gd)
use_imagick = false;
 

следующий шаг:

Открываем файл api/Image.php

прошерстив код - увидел, и в самом деле watermark добавляется после ресайза, значит нужно чтото делать, а именно: 

поскольку мы переключились на библиотеку gd значит нам нужен метод image_constrain_gd он находится у меня на строке 174

там ищем такой код:

 

 

// Watermark
if(!empty($watermark) && is_readable($watermark))
{
$overlay = imagecreatefrompng($watermark);

// Get the size of overlay
$owidth = imagesx($overlay);
$oheight = imagesy($overlay);

$watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/100, $dst_w);
$watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/100, $dst_h);

imagecopy($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);
//imagecopymerge($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight, $watermark_opacity*100);
 

его мы коментируем и вставляем после того как мы прочли файл а значит вставляем его после строчки 

 

  

 

if(empty($src_img))
  return false;
 

и заменяем строку в строке $dst_img на $src_img

 

 

//imagecopy($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);
imagecopy($src_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);
 

вот и все, спасибо за внимание. 

 

 

 

Link to post
Share on other sites

 

Открываем файл api/Image.php

прошерстив код - увидел, и в самом деле watermark добавляется после ресайза, значит нужно чтото делать, а именно: 

поскольку мы переключились на библиотеку gd значит нам нужен метод image_constrain_gd он находится у меня на строке 174

там ищем такой код:

 

 

// Watermark
if(!empty($watermark) && is_readable($watermark))
{
$overlay = imagecreatefrompng($watermark);

// Get the size of overlay
$owidth = imagesx($overlay);
$oheight = imagesy($overlay);

$watermark_x = min(($dst_w-$owidth)*$watermark_offet_x/100, $dst_w);
$watermark_y = min(($dst_h-$oheight)*$watermark_offet_y/100, $dst_h);

imagecopy($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);
//imagecopymerge($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight, $watermark_opacity*100);
 

 

 

его мы коментируем и вставляем после того как мы прочли файл а значит вставляем его после строчки 

 

 

if(empty($src_img))
  return false;

 

и заменяем строку в строке $dst_img на $src_img

//imagecopy($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);
imagecopy($src_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);

вот и все, спасибо за внимание. 

 

 

то что я написал вчера в принципе все нормально кроме того что water mark появляется в том месте где он должен быть после ресайза об этом говорят переменные   $watermark_x и  $watermark_y поэтому мы должны так же поправить и их вместо $dst_w и $dst_h на $src_w и $src_h:

 

поэтому держите готовый кусок кода:

 

 

// Watermark
if(!empty($watermark) && is_readable($watermark))
{
$overlay = imagecreatefrompng($watermark);

// Get the size of overlay
$owidth = imagesx($overlay);
$oheight = imagesy($overlay);

$watermark_x = min(($src_w-$owidth)*$watermark_offet_x/100, $src_w);
$watermark_y = min(($src_h-$oheight)*$watermark_offet_y/100, $src_h);

imagecopy($src_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight);
//imagecopymerge($dst_img, $overlay, $watermark_x, $watermark_y, 0, 0, $owidth, $oheight, $watermark_opacity*100);
 

 

 

}

Edited by esperantic
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...