Размещение фотографий

Пишите о найденных ошибках в эту тему

Модераторы: Xpycm, Koduc

Правила форума
ВНИМАНИЕ! Форум не является средством гарантированной поддержки клиентов и пользователей. Поэтому на быстрый ответ тут рассчитывать не нужно, как и на ответ вообще. Сотрудники отвечают по мере своих возможностей.

На форуме действует ограничение в 3 сообщения / сутки.
Если Вы хотите сказать "спасибо", то воспользуйтесь функцией "Повысить репутацию" - зелёная иконка "плюс" под ником ответившего.

Размещение фотографий

Сообщение Вера » 29 авг 2016, 14:59

Добрый день! Создали сайт агентства недвижимости, но фотографии перестали размещаться, идет информация "ошибка". Подскажите, что надо сделать?
Вера
Незнакомец
 
Сообщения: 1
Зарегистрирован: 29 авг 2016, 14:31
Очки репутации: 0

Re: Размещение фотографий

Сообщение Xpycm » 29 авг 2016, 16:08

Здравствуйте.

1) Включить дебаг режим: https://open-real-estate.info/ru/faq#debug-mode
Посмотреть во вкладке Сеть консоли браузера (инструменты разработчика, - Chrome или расширение FireBug для FireFox) на текст ошибки.

2) Попробовать загрузить изображение и сразу же посмотреть логи сервера. Скорее всего ошибка также будет видна ( файл и строка в которой возникает проблема )

А также, проверьте права на запись для папки uploads и вложенных к неё.
Ещё, как вариант, возможно, включено расширение mod_security, то воспользоваться таким решением: https://monoray.net/forum/viewtopic.php?f=6&t=767
Dropbox
Open Real Estate CMS: FAQ | FAQ 2 | FAQ 3
Изображение
Xpycm
Разработчик
Разработчик
 
Сообщения: 1592
Зарегистрирован: 30 дек 2011, 11:06
Откуда: Йошкар-Ола
Очки репутации: 50

Re: Размещение фотографий

Сообщение mrweb777 » 21 окт 2016, 13:56

Доброго времени суток.
Xpycm, мы включили дебаг режим.
Сегодня утром я решил загрузить фотографию, и посмотреть на неё средствами chrome, у меня действительно появилась ошибка, указывающая что я пытался загрузить фотографию большим размером чем выделено памяти, но если на неё посмотреть...
Код: Выделить всё
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 17280 bytes) in /home/virtwww/user/http/protected/modules/images/components/CImageHandler.php on line 175

становиться понятно, то что место на диске есть.
Вот эта функция в которой была ошибка:
Код: Выделить всё
protected function initImage($image = false)
    {
        if($image === false)
        {
            $image = $this->originalImage;
        }

        $this->width = $image['width'];
        $this->height = $image['height'];
        $this->mimeType = $image['mimeType'];
        $this->format = $image['format'];

        //Image
        if(is_resource($this->image))
            imagedestroy($this->image);

        $this->image = imagecreatetruecolor($this->width, $this->height);
        $this->preserveTransparency($this->image);
        imagecopy($this->image, $image['image'], 0, 0, 0, 0, $this->width, $this->height);
    

Если точно, то 175 строка:
Код: Выделить всё
$this->image = imagecreatetruecolor($this->width, $this->height); 

И ещё... Прослеживается такая вещь, иногда фотографии загружаются, создаётся впечатление что дело в самих фото, хочу уточнить, что загружаются "лёгкие изображения".(Но обычно и они не загружаються)
P.S: Действительно права на папках вложенных в uploads были выставлены: 0755, я выставил 0777 для uploads и всех в неё вложенных, но это не помогло, mod_security отключён.

Полный файл с ошибкой
Код: Выделить всё
<?php
/**
 * Image handler
 * @author Yaroslav Pelesh aka Tokolist http://tokolist.com
 * @link https://github.com/tokolist/yii-components
 * @version 1.2
 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
 */

class CImageHandler extends CApplicationComponent
{
    private $originalImage = null;
    private $image = null;

    private $format = 0;

    private $width = 0;
    private $height = 0;

    private $mimeType = '';

    private $fileName = '';

    public $transparencyColor = array(0, 0, 0);


    const IMG_GIF = 1;
    const IMG_JPEG = 2;
    const IMG_PNG = 3;

    const CORNER_LEFT_TOP = 1;
    const CORNER_RIGHT_TOP = 2;
    const CORNER_LEFT_BOTTOM = 3;
    const CORNER_RIGHT_BOTTOM = 4;
    const CORNER_CENTER = 5;

    const CORNER_CENTER_TOP = 6;
    const CORNER_CENTER_BOTTOM = 7;
    const CORNER_LEFT_CENTER = 8;
    const CORNER_RIGHT_CENTER = 9;

    const FLIP_HORIZONTAL = 1;
    const FLIP_VERTICAL = 2;
    const FLIP_BOTH = 3;


    public function getImage()
    {
        return $this->image;
    }

    public function getFormat()
    {
        return $this->format;
    }

    public function getWidth()
    {
        return $this->width;
    }

    public function getHeight()
    {
        return $this->height;
    }

    public function getMimeType()
    {
        return $this->mimeType;
    }

    public function __destruct()
    {
        $this->freeImage();
    }

    private function freeImage()
    {
        if(is_resource($this->image))
        {
            imagedestroy($this->image);
        }

        if($this->originalImage !== null)
        {
            if(is_resource($this->originalImage['image']))
            {
                imagedestroy($this->originalImage['image']);
            }
            $this->originalImage = null;
        }
    }

    private function checkLoaded()
    {
        if (!is_resource($this->image))
        {
            throw new Exception('Load image first');
        }
    }

    private function loadImage($file)
    {
        $result = array();



        if ($imageInfo = @getimagesize($file))
        {
            $result['width'] = $imageInfo[0];
            $result['height'] = $imageInfo[1];

            $result['mimeType'] = $imageInfo['mime'];

            switch ($result['format'] = $imageInfo[2])
            {
                case self::IMG_GIF:
                    if ($result['image'] = imagecreatefromgif($file))
                    {
                        return $result;
                    }
                    else
                    
{
                        throw new Exception('Invalid image gif format');
                    }
                    break;
                case self::IMG_JPEG:
                    if ($result['image'] = imagecreatefromjpeg($file))
                    {
                        return $result;
                    }
                    else
                    
{
                        throw new Exception('Invalid image jpeg format');
                    }
                    break;
                case self::IMG_PNG:
                    if ($result['image'] = imagecreatefrompng($file))
                    {
                        return $result;
                    }
                    else
                    
{
                        throw new Exception('Invalid image png format');
                    }
                    break;
                  default:
                      throw new Exception('Not supported image format');
              }
          }
          else
          
{
              throw new Exception('Invalid image file');
          }


    }

    protected function initImage($image = false)
    {
        if($image === false)
        {
            $image = $this->originalImage;
        }

        $this->width = $image['width'];
        $this->height = $image['height'];
        $this->mimeType = $image['mimeType'];
        $this->format = $image['format'];

        //Image
        if(is_resource($this->image))
            imagedestroy($this->image);

        $this->image = imagecreatetruecolor($this->width, $this->height);
        $this->preserveTransparency($this->image);
        imagecopy($this->image, $image['image'], 0, 0, 0, 0, $this->width, $this->height);
    }

    public function load($file)
    {
        $this->freeImage();

        if(($this->originalImage = $this->loadImage($file)))
        {
            $this->initImage();
            $this->fileName = $file;


            return $this;
        }
        else
        
{
            return false;
        }
    }

    public function reload()
    {
        $this->checkLoaded();
        $this->initImage();

        return $this;
    }

    private function preserveTransparency($newImage)
    {
        switch($this->format)
        {
            case self::IMG_GIF:
                $color = imagecolorallocate(
                    $newImage,
                    $this->transparencyColor[0],
                    $this->transparencyColor[1],
                    $this->transparencyColor[2]
                );

                imagecolortransparent($newImage, $color);
                imagetruecolortopalette($newImage, false, 256);
                break;
            case self::IMG_PNG:
                imagealphablending($newImage, false);

                $color = imagecolorallocatealpha (
                    $newImage,
                    $this->transparencyColor[0],
                    $this->transparencyColor[1],
                    $this->transparencyColor[2],
                    0
                
);

                imagefill($newImage, 0, 0, $color);
                imagesavealpha($newImage, true);
                break;
        }
    }

    public function resize($toWidth, $toHeight, $proportional = true)
    {
        $this->checkLoaded();

        $toWidth = $toWidth !== false ? $toWidth : $this->width;
        $toHeight = $toHeight !== false ? $toHeight : $this->height;

        if($proportional)
        {
            $newHeight = $toHeight;
            $newWidth = round($newHeight / $this->height * $this->width);


            if($newWidth > $toWidth)
            {
                $newWidth = $toWidth;
                $newHeight = round($newWidth / $this->width * $this->height);
            }
        }
        else
        
{
            $newWidth = $toWidth;
            $newHeight = $toHeight;
        }

        $newImage = imagecreatetruecolor($newWidth, $newHeight);

        $this->preserveTransparency($newImage);

        imagecopyresampled($newImage, $this->image, 0, 0, 0, 0, $newWidth, $newHeight, $this->width, $this->height);



        imagedestroy($this->image);

        $this->image = $newImage;
        $this->width = $newWidth;
        $this->height = $newHeight;

        return $this;

    }

    public function thumb($toWidth, $toHeight, $proportional = true)
    {
        $this->checkLoaded();

        if($toWidth !== false)
            $toWidth = min($toWidth, $this->width);

        if($toHeight !== false)
            $toHeight = min($toHeight, $this->height);


        $this->resize($toWidth, $toHeight, $proportional);

        return $this;

    }

    public function watermark($watermarkFile, $offsetX, $offsetY, $corner = self::CORNER_RIGHT_BOTTOM, $zoom = false)
    {

        $this->checkLoaded();

        if ($wImg = $this->loadImage($watermarkFile))
        {

            $posX = 0;
            $posY = 0;

            $watermarkWidth = $wImg['width'];
            $watermarkHeight = $wImg['height'];

            if($zoom !== false)
            {
                $dimension = round(max($this->width, $this->height) * $zoom);

                $watermarkHeight = $dimension;
                $watermarkWidth = round($watermarkHeight / $wImg['height'] * $wImg['width']);

                if($watermarkWidth > $dimension)
                {
                    $watermarkWidth = $dimension;
                    $watermarkHeight = round($watermarkWidth / $wImg['width'] * $wImg['height']);
                }
            }

            switch ($corner)
            {
                case self::CORNER_LEFT_TOP:
                    $posX = $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_RIGHT_TOP:
                    $posX = $this->width - $watermarkWidth - $offsetX;
                    $posY = $offsetY;
                    break;
                case self::CORNER_LEFT_BOTTOM:
                    $posX = $offsetX;
                    $posY = $this->height - $watermarkHeight - $offsetY;
                    break;
                case self::CORNER_RIGHT_BOTTOM:
                    $posX = $this->width - $watermarkWidth - $offsetX;
                    $posY = $this->height - $watermarkHeight - $offsetY;
                    break;
                case self::CORNER_CENTER:
                    $posX = floor(($this->width - $watermarkWidth) / 2);
                    $posY = floor(($this->height - $watermarkHeight) / 2);
                    break;

                case self::CORNER_CENTER_TOP:
                    $posX = floor(($this->width - $watermarkWidth) / 2);
                    $posY = $offsetY;
                    break;
                case self::CORNER_CENTER_BOTTOM:
                    $posX = floor(($this->width - $watermarkWidth) / 2);
                    $posY = $this->height - $watermarkHeight - $offsetY;
                    break;
                case self::CORNER_LEFT_CENTER:
                    $posX = $offsetX;
                    $posY = floor(($this->height - $watermarkHeight) / 2);
                    break;
                case self::CORNER_RIGHT_CENTER:
                    $posX = $this->width - $watermarkWidth - $offsetX;
                    $posY = floor(($this->height - $watermarkHeight) / 2);
                    break;

                default:
                    throw new Exception('Invalid $corner value');
            }

            if($this->format == self::IMG_PNG){
                imagealphablending($this->image,1);
                imagesavealpha($this->image,1);
                imagealphablending($wImg['image'],1);
                imagesavealpha($wImg['image'],1);
                imagecopy($this->image, $wImg['image'], $posX, $posY, 0, 0, $wImg['width'], $wImg['height']);
            }

            imagecopyresampled(
                $this->image,
                $wImg['image'],
                $posX,
                $posY,
                0,
                0,
                $watermarkWidth,
                $watermarkHeight,
                $wImg['width'],
                $wImg['height']
            );


            imagedestroy($wImg['image']);

            return $this;
        }
        else
        
{
            return false;
        }
    }


    public function flip($mode)
    {
        $this->checkLoaded();

        $srcX = 0;
        $srcY = 0;
        $srcWidth = $this->width;
        $srcHeight = $this->height;

        switch ($mode)
        {
            case self::FLIP_HORIZONTAL:
                $srcX = $this->width - 1;
                $srcWidth = -$this->width;
                break;
            case self::FLIP_VERTICAL:
                $srcY = $this->height - 1;
                $srcHeight = -$this->height;
                break;
            case self::FLIP_BOTH:
                $srcX = $this->width - 1;
                $srcY = $this->height - 1;
                $srcWidth = -$this->width;
                $srcHeight = -$this->height;
                break;
            default:
                throw new Exception('Invalid $mode value');
        }

        $newImage = imagecreatetruecolor($this->width, $this->height);
        $this->preserveTransparency($newImage);

        imagecopyresampled($newImage, $this->image, 0, 0, $srcX, $srcY, $this->width, $this->height, $srcWidth, $srcHeight);

        imagedestroy($this->image);

        $this->image = $newImage;
        //dimensions not changed

        return $this;
    }

    public function rotate($degrees)
    {
        $this->checkLoaded();

        $degrees = (int) $degrees;
        $this->image = imagerotate($this->image, $degrees, 0);

        $this->width = imagesx($this->image);
        $this->height = imagesy($this->image);

        return $this;
    }

    public function crop($width, $height, $startX = false, $startY = false)
    {
        $this->checkLoaded();

        $width = (int) $width;
        $height = (int) $height;

        //Centered crop
         $startX = $startX === false ? floor(($this->width - $width) / 2) : intval($startX);
        $startY = $startY === false ? floor(($this->height - $height) / 2) : intval($startY);

        //Check dimensions
        $startX = max(0, min($this->width, $startX));
        $startY = max(0, min($this->height, $startY));
        $width = min($width, $this->width - $startX);
        $height = min($height, $this->height - $startY);


        $newImage = imagecreatetruecolor($width, $height);

        $this->preserveTransparency($newImage);

        imagecopyresampled($newImage, $this->image, 0, 0, $startX, $startY, $width, $height, $width, $height);

        imagedestroy($this->image);

        $this->image = $newImage;
        $this->width = $width;
        $this->height = $height;

        return $this;
    }

    public function text($text, $fontFile, $size=12, $color=array(0, 0, 0),
        $corner=self::CORNER_LEFT_TOP, $offsetX=0, $offsetY=0, $angle=0, $alpha = 0)
    {
        $this->checkLoaded();

        $bBox = imagettfbbox($size, $angle, $fontFile, $text);
        $textHeight = $bBox[1] - $bBox[7];
        $textWidth = $bBox[2] - $bBox[0];

        switch ($corner)
        {
            case self::CORNER_LEFT_TOP:
                $posX = $offsetX;
                $posY = $offsetY;
                break;
            case self::CORNER_RIGHT_TOP:
                $posX = $this->width - $textWidth - $offsetX;
                $posY = $offsetY;
                break;
            case self::CORNER_LEFT_BOTTOM:
                $posX = $offsetX;
                $posY = $this->height - $textHeight - $offsetY;
                break;
            case self::CORNER_RIGHT_BOTTOM:
                $posX = $this->width - $textWidth - $offsetX;
                $posY = $this->height - $textHeight - $offsetY;
                break;
            case self::CORNER_CENTER:
                $posX = floor(($this->width - $textWidth) / 2);
                $posY = floor(($this->height - $textHeight) / 2);
                break;

            case self::CORNER_CENTER_TOP:
                $posX = floor(($this->width - $textWidth) / 2);
                $posY = $offsetY;
                break;
            case self::CORNER_CENTER_BOTTOM:
                $posX = floor(($this->width - $textWidth) / 2);
                $posY = $this->height - $textHeight - $offsetY;
                break;
            case self::CORNER_LEFT_CENTER:
                $posX = $offsetX;
                $posY = floor(($this->height - $textHeight) / 2);
                break;
            case self::CORNER_RIGHT_CENTER:
                $posX = $this->width - $textWidth - $offsetX;
                $posY = floor(($this->height - $textHeight) / 2);
                break;

            default:
                throw new Exception('Invalid $corner value');
        }

        if($alpha > 0){
            $color =  imagecolorallocatealpha($this->image, $color[0], $color[1], $color[2], $alpha);
        } else {
            $color = imagecolorallocate($this->image, $color[0], $color[1], $color[2]);
        }

        if($this->format == self::IMG_PNG){
            imagealphablending($this->image, true); 
            imagesavealpha
($this->image, true);
        }

        imagettftext($this->image, $size, $angle, $posX, $posY + $textHeight, $color, $fontFile, $text);

        return $this;
    }

    public function adaptiveThumb($width, $height)
    {
        $this->checkLoaded();

        $width = intval($width);
        $height = intval($height);

        $widthProportion = $width / $this->width;
        $heightProportion = $height / $this->height;

        if ($widthProportion > $heightProportion)
        {
            $newWidth = $width;
            $newHeight = round($newWidth / $this->width * $this->height);
        }
        else
        
{
            $newHeight = $height;
            $newWidth = round($newHeight / $this->height * $this->width);
        }

        $this->resize($newWidth, $newHeight);

        $this->crop($width, $height);

        return $this;
    }

    public function resizeCanvas($toWidth, $toHeight, $backgroundColor = array(255, 255, 255))
    {
        $this->checkLoaded();

        $newWidth = min($toWidth, $this->width);
        $newHeight = min($toHeight, $this->height);

        $widthProportion = $newWidth / $this->width;
        $heightProportion = $newHeight / $this->height;

        if($widthProportion < $heightProportion)
        {
            $newHeight = round($widthProportion * $this->height);
        }
        else
        
{
            $newWidth = round($heightProportion * $this->width);
        }

        $posX = floor(($toWidth - $newWidth) / 2);
        $posY = floor(($toHeight - $newHeight) / 2);


        $newImage = imagecreatetruecolor($toWidth, $toHeight);

        $backgroundColor = imagecolorallocate($newImage, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2]);
        imagefill($newImage, 0, 0, $backgroundColor);

        imagecopyresampled($newImage, $this->image, $posX, $posY, 0, 0, $newWidth, $newHeight, $this->width, $this->height);

        imagedestroy($this->image);

        $this->image = $newImage;
        $this->width = $toWidth;
        $this->height = $toHeight;

        return $this;
    }

    public function grayscale()
    {
        $newImage = imagecreatetruecolor($this->width, $this->height);

        imagecopy($newImage, $this->image, 0, 0, 0, 0, $this->width, $this->height);
        imagecopymergegray($newImage, $newImage, 0, 0, 0, 0, $this->width, $this->height, 0);

        imagedestroy($this->image);

        $this->image = $newImage;

        return $this;
    }

    public function show($inFormat = false, $jpegQuality = 75)
    {
        $this->checkLoaded();

        if (!$inFormat)
        {
            $inFormat = $this->format;
        }

        switch ($inFormat)
        {
            case self::IMG_GIF:
                header('Content-type: image/gif');
                imagegif($this->image);
                break;
            case self::IMG_JPEG:
                header('Content-type: image/jpeg');
                imagejpeg($this->image, null, $jpegQuality);
                break;
            case self::IMG_PNG:
                header('Content-type: image/png');
                imagepng($this->image);
                break;
            default:
                throw new Exception('Invalid image format for putput');
        }

        return $this;
    }

    public function save($file = false, $toFormat = false, $jpegQuality = 75, $touch = false)
    {
        if (empty($file))
        {
            $file = $this->fileName;
        }

        $this->checkLoaded();

        if (!$toFormat)
        {
            $toFormat = $this->format;
        }

        switch ($toFormat)
        {
            case self::IMG_GIF:
                if (!imagegif($this->image, $file))
                {
                    throw new Exception('Can\'t save gif file');
                }
                break;
            case self::IMG_JPEG:
                if (!imagejpeg($this->image, $file, $jpegQuality))
                {
                    throw new Exception('Can\'t save jpeg file');
                }
                break;
            case self::IMG_PNG:
                if (!imagepng($this->image, $file))
                {
                    throw new Exception('Can\'t save png file');
                }
                break;
            default:
                throw new Exception('Invalid image format for save');
        }

        if ($touch && $file != $this->fileName)
        {
            touch($file, filemtime($this->fileName));
        }

        return $this;
    }

}
mrweb777
Незнакомец
 
Сообщения: 1
Зарегистрирован: 21 окт 2016, 13:38
Очки репутации: 0

Re: Размещение фотографий

Сообщение Xpycm » 21 окт 2016, 16:41

Здравствуйте.

Если погуглить по ошибке, которая возникает, то сразу куча ответов:
https://www.google.ru/search?q=Fatal+er ... +exhausted

Дело не в свободном месте на жёстком диске, а в том, что php не хватает памяти, чтобы обработать фотографию - уменьшить/наложить водяной знак или ещё что-либо.

Необходимо увеличить ОЗУ, которая выделена для PHP
Dropbox
Open Real Estate CMS: FAQ | FAQ 2 | FAQ 3
Изображение
Xpycm
Разработчик
Разработчик
 
Сообщения: 1592
Зарегистрирован: 30 дек 2011, 11:06
Откуда: Йошкар-Ола
Очки репутации: 50


Вернуться в Ошибки

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

cron