Вход Регистрация
Файл: contao-3.5.8/system/modules/core/library/Contao/GdImage.php
Строк: 257
<?php

/**
 * Contao Open Source CMS
 *
 * Copyright (c) 2005-2016 Leo Feyer
 *
 * @license LGPL-3.0+
 */

namespace Contao;


/**
 * GD image class
 *
 * The class handles GD images.
 *
 * Usage:
 *
 *     $source = GdImage::fromFile($objFile);
 *     $target = GdImage::fromDimensions(100, 100);
 *
 *     $source->copyTo($target, 0, 0, 100, 100);
 *     $target->convertToPaletteImage()
 *            ->saveToFile('image.jpg');
 *
 * @author Leo Feyer <https://github.com/leofeyer>
 */
class GdImage
{

    
/**
     * The GD resource handle
     *
     * @var resource
     */
    
protected $gdResource null;


    
/**
     * Create a new object to handle a GD image
     *
     * @param resource $gdResource The GD resource handle
     */
    
public function __construct($gdResource)
    {
        
$this->setResource($gdResource);
    }


    
/**
     * Get the GD image object from an image file
     *
     * @param File $file The file object
     *
     * @return static The GD image object
     *
     * @throws InvalidArgumentException If the image type cannot be processed
     * @throws RuntimeException         If the image failed to be processed
     */
    
public static function fromFile(File $file)
    {
        
$extension strtolower($file->extension);
        
$function null;

        if (
$extension === 'jpg')
        {
            
$extension 'jpeg';
        }

        if (
in_array($extension, array('gif''jpeg''png')))
        {
            
$function 'imagecreatefrom' $extension;
        }

        if (
$function === null || !is_callable($function))
        {
            throw new 
InvalidArgumentException('Image type "' $file->extension '" cannot be processed by GD');
        }

        
$image $function(TL_ROOT '/' $file->path);

        if (
$image === false)
        {
            throw new 
RuntimeException('Image "' $file->path '" failed to be processed by GD');
        }

        return new static(
$image);
    }


    
/**
     * Get the GD image object for the specified dimensions
     *
     * @param integer $width  The image width
     * @param integer $height The image height
     *
     * @return static The GD image object
     */
    
public static function fromDimensions($width$height)
    {
        
$image imagecreatetruecolor($width$height);

        
$arrGdInfo gd_info();
        
$strGdVersion preg_replace('/[^0-9.]+/'''$arrGdInfo['GD Version']);

        
// Handle transparency (GDlib >= 2.0 required)
        
if (version_compare($strGdVersion'2.0''>='))
        {
            
imagealphablending($imagefalse);
            
imagefill($image00imagecolorallocatealpha($image000127));
            
imagesavealpha($imagetrue);
        }

        return new static(
$image);
    }


    
/**
     * Get the GD resource handle
     *
     * @return resource The GD resource handle
     */
    
public function getResource()
    {
        return 
$this->gdResource;
    }


    
/**
     * Set the GD resource handle
     *
     * @param resource $gdResource The GD resource handle
     *
     * @return static
     *
     * @throws InvalidArgumentException If $gdResource is not a GD resource
     */
    
public function setResource($gdResource)
    {
        if (!
is_resource($gdResource) || get_resource_type($gdResource) !== 'gd')
        {
            throw new 
InvalidArgumentException('$gdResource is not a valid GD resource');
        }

        
$this->gdResource $gdResource;

        return 
$this;
    }


    
/**
     * Save the GD image to a file
     *
     * @param string $path The image path
     *
     * @return static
     *
     * @throws InvalidArgumentException If the image type cannot be generated
     */
    
public function saveToFile($path)
    {
        
$arrGdInfo gd_info();
        
$extension strtolower(pathinfo($pathPATHINFO_EXTENSION));

        
// Fallback to PNG if GIF ist not supported
        
if ($extension == 'gif' && !$arrGdInfo['GIF Create Support'])
        {
            
$extension 'png';
        }

        
// Create the new image
        
switch ($extension)
        {
            case 
'gif':
                
$this->convertToPaletteImage();
                
imagegif($this->gdResource$path);
                break;

            case 
'jpg':
            case 
'jpeg':
                
imageinterlace($this->gdResource1); // see #6529
                
imagejpeg($this->gdResource$path, (Config::get('jpgQuality') ?: 80));
                break;

            case 
'png':
                if (
$this->countColors(256) <= 256 && !$this->isSemitransparent())
                {
                    
$this->convertToPaletteImage();
                }
                
imagepng($this->gdResource$path);
                break;

            default:
                throw new 
InvalidArgumentException('Image type "' $extension '" cannot be generated');
                break;
        }

        return 
$this;
    }


    
/**
     * Save the GD image to a file
     *
     * @param self    $gdImage The target GD image
     * @param integer $x       The target X coordinate
     * @param integer $y       The target Y coordinate
     * @param integer $width   The target width
     * @param integer $height  The target height
     *
     * @return static
     */
    
public function copyTo(self $gdImage$x$y$width$height)
    {
        
imagecopyresampled($gdImage->getResource(), $this->gdResource$x$y00$width$heightimagesx($this->gdResource), imagesy($this->gdResource));

        return 
$this;
    }


    
/**
     * Convert a true color image to a palette image with 256 colors and preserve transparency
     *
     * @return static
     */
    
public function convertToPaletteImage()
    {
        if (!
imageistruecolor($this->gdResource))
        {
            return 
$this;
        }

        
$width imagesx($this->gdResource);
        
$height imagesy($this->gdResource);

        
$transparentColor null;

        if (
$this->countColors(256) <= 256)
        {
            
$paletteImage imagecreate($width$height);
            
$colors = array();
            
$isTransparent false;

            for (
$x 0$x $width$x++)
            {
                for (
$y 0$y $height$y++)
                {
                    
$color imagecolorat($this->gdResource$x$y);

                    
// Check if the pixel is fully transparent
                    
if ((($color >> 24) & 0x7F) === 127)
                    {
                        
$isTransparent true;
                    }
                    else
                    {
                        
$colors[$color 0xFFFFFF] = true;
                    }
                }
            }

            
$colors array_keys($colors);

            foreach (
$colors as $index => $color)
            {
                
imagecolorset($paletteImage$index, ($color >> 16) & 0xFF, ($color >> 8) & 0xFF$color 0xFF);
            }

            if (
$isTransparent)
            {
                
$transparentColor imagecolorallocate($paletteImage000);
                
imagecolortransparent($paletteImage$transparentColor);
            }

            
imagecopy($paletteImage$this->gdResource0000$width$height);
        }
        else
        {
            
$paletteImage imagecreatetruecolor($width$height);
            
imagealphablending($paletteImagefalse);
            
imagesavealpha($paletteImagetrue);
            
imagecopy($paletteImage$this->gdResource0000$width$height);

            
// 256 minus 1 for the transparent color
            
imagetruecolortopalette($paletteImagefalse255);
            
$transparentColor imagecolorallocate($paletteImage000);
            
imagecolortransparent($paletteImage$transparentColor);
        }

        if (
$transparentColor !== null)
        {
            
// Fix fully transparent pixels
            
for ($x 0$x $width$x++)
            {
                for (
$y 0$y $height$y++)
                {
                    
// Check if the pixel is fully transparent
                    
if (((imagecolorat($this->gdResource$x$y) >> 24) & 0x7F) === 127)
                    {
                        
imagefilledrectangle($paletteImage$x$y$x$y$transparentColor);
                    }
                }
            }
        }

        
imagedestroy($this->gdResource);
        
$this->gdResource $paletteImage;

        return 
$this;
    }


    
/**
     * Count the number of colors in the image
     *
     * @param integer $max Stop parsing the image if more colors than $max were found
     *
     * @return integer The number of image colors
     */
    
public function countColors($max null)
    {
        if (!
imageistruecolor($this->gdResource))
        {
            return 
imagecolorstotal($this->gdResource);
        }

        
$colors = array();
        
$width imagesx($this->gdResource);
        
$height imagesy($this->gdResource);

        for (
$x 0$x $width$x++)
        {
            for (
$y 0$y $height$y++)
            {
                
$colors[imagecolorat($this->gdResource$x$y)] = true;

                if (
$max !== null && count($colors) > $max)
                {
                    break 
2;
                }
            }
        }

        return 
count($colors);
    }


    
/**
     * Detect if the image contains semitransparent pixels
     *
     * @return boolean True if the image contains semitransparent pixels
     */
    
public function isSemitransparent()
    {
        if (!
imageistruecolor($this->gdResource))
        {
            return 
false;
        }

        
$width imagesx($this->gdResource);
        
$height imagesy($this->gdResource);

        for (
$x 0$x $width$x++)
        {
            for (
$y 0$y $height$y++)
            {
                
// Check if the pixel is semitransparent
                
$alpha = (imagecolorat($this->gdResource$x$y) >> 24) & 0x7F;

                if (
$alpha && $alpha 127)
                {
                    return 
true;
                }
            }
        }

        return 
false;
    }


    
/**
     * Destroy the GD resource to free memory
     */
    
public function __destruct()
    {
        if (
is_resource($this->gdResource))
        {
            
imagedestroy($this->gdResource);
        }
    }
}
Онлайн: 1
Реклама