Перейти к содержанию
Официальный форум поддержки Simpla

Рекомендуемые сообщения

Подскажите как добавить 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;  
    }
    
}
 
Изменено пользователем Amarous
Ссылка на сообщение
Поделиться на другие сайты

а не проще сам watermark сделать меньше в фотошопе, чем применять функцию в php для его уменьшения?

Ссылка на сообщение
Поделиться на другие сайты

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

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

Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Ссылка на сообщение
Поделиться на другие сайты
  • 10 месяцев спустя...

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

для начала у меня не хотела заводится прозрозрачность водяного знака, для этого я изменил библиотеку работы с изображениями с 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);
 

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

 

 

 

Ссылка на сообщение
Поделиться на другие сайты

 

Открываем файл 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);
 

 

 

}

Изменено пользователем esperantic
Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...