/**
  * Hex darker/lighter/contrast functions for colours
  *
  * @access public
  * @param mixed $color
  * @param int $factor (default: 30)
  * @return string
  */
 function hex_lighter($color, $factor = 30)
 {
     $base = rgb_from_hex($color);
     $color = '#';
     foreach ($base as $k => $v) {
         $amount = 255 - $v;
         $amount = $amount / 100;
         $amount = round($amount * $factor);
         $new_decimal = $v + $amount;
         $new_hex_component = dechex($new_decimal);
         if (strlen($new_hex_component) < 2) {
             $new_hex_component = "0" . $new_hex_component;
         }
         $color .= $new_hex_component;
     }
     return $color;
 }
function resizeAndCache($finalSize, $paths, $params)
{
    // Target dimensions
    $width = $finalSize[0];
    $height = $finalSize[1];
    // Original dimensions
    list($oldWidth, $oldHeight, $imgType) = getimagesize($paths['fileSrc']);
    // Don't resize if we don't need to
    if ($width >= $oldWidth && $height >= $oldHeight && !$params['bw'] && !$params['radius']) {
        return $paths['fileUrl'];
    }
    // Create a name and path for the cached file
    $cachedName = $paths['fileBasename'] . '-' . $width . 'x' . $height;
    $cachedName .= $params['bw'] ? '-bw' : '';
    $cachedName .= $params['colorize'] ? '-c' . trim($params['colorize'], '#') : '';
    $cachedName .= $params['radius'] ? '-r' . $params['radius'] . trim($params['background'], '#') : '';
    $cachedName .= $params['forcepng'] ? '.png' : '.' . $paths['fileExt'];
    $cachedPath = $paths['cachePath'] . $cachedName;
    $cachedUrl = $paths['cacheUrl'] . $cachedName;
    // Unless there's already a cached version, create one
    $imageTime = @filemtime($paths['fileSrc']);
    $cacheTime = @filemtime($cachedPath);
    if (!is_file($cachedPath) || $imageTime > $cacheTime) {
        // Read the image into memory
        switch ($imgType) {
            case IMAGETYPE_GIF:
                $image = imagecreatefromgif($paths['fileSrc']);
                break;
            case IMAGETYPE_JPEG:
                $image = imagecreatefromjpeg($paths['fileSrc']);
                break;
            case IMAGETYPE_PNG:
                $image = imagecreatefrompng($paths['fileSrc']);
                break;
            default:
                return false;
        }
        // Create a new blank image to hold the resized image
        $newImage = imagecreatetruecolor($width, $height);
        if (!$finalSize[2]) {
            // Resize it - no cropping needed
            imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, $oldWidth, $oldHeight);
        } else {
            // Resize and crop
            $oldRatio = $oldWidth / $oldHeight;
            $newRatio = $width / $height;
            if ($oldRatio > $newRatio) {
                // Crop the width
                $adjustedWidth = floor($oldWidth * ($height / $oldHeight));
                $adjustedHeight = $height;
                $widthMargin = ($adjustedWidth - $width) / 2;
            } elseif ($oldRatio < $newRatio) {
                // Crop the height
                $adjustedHeight = floor($oldHeight * ($width / $oldWidth));
                $adjustedWidth = $width;
                $heightMargin = ($adjustedHeight - $height) / 2;
            }
            imagecopyresampled($newImage, $image, -$widthMargin, -$heightMargin, 0, 0, $adjustedWidth, $adjustedHeight, $oldWidth, $oldHeight);
        }
        // Do the greyscale conversion
        if ($params['bw']) {
            imagefilter($image, IMG_FILTER_GRAYSCALE);
        } elseif ($params['colorize']) {
            $rgb = rgb_from_hex($params['colorize']);
            imagefilter($newImage, IMG_FILTER_GRAYSCALE);
            imagefilter($newImage, IMG_FILTER_COLORIZE, $rgb['r'], $rgb['g'], $rgb['b']);
        }
        // Add rounded corners
        if ($params['radius']) {
            // Create a new image to hold the alpha mask
            $mask = imagecreatetruecolor($width, $height);
            imagealphablending($mask, true);
            $trans = imagecolorallocatealpha($mask, 0, 0, 0, 127);
            $black = imagecolorallocatealpha($mask, 0, 0, 0, 0);
            // Convert to true color, if needed
            if (!imageistruecolor($newImage)) {
                $tmpImage = imagecreatetruecolor($width, $height);
                imagecopy($tmpImage, $newImage, 0, 0, 0, 0, $width, $height);
                $newImage = $tmpImage;
            }
            // Draw the mask with rounded corners
            $radius = $params['radius'];
            $diameter = $radius * 2;
            imagefill($mask, 0, 0, $trans);
            imagefilledrectangle($mask, $radius, 0, $width - $radius, $height, $black);
            imagefilledrectangle($mask, 0, $radius, $width, $height - $radius, $black);
            $fillcolor = array(0, 0, 0, 0);
            imageSmoothArc($mask, $radius, $radius + 1, $diameter, $diameter, $fillcolor, 0, 12);
            //TL
            imageSmoothArc($mask, $width - $radius - 2, $radius + 1, $diameter, $diameter, $fillcolor, 0, 12);
            //TR
            imageSmoothArc($mask, $radius, $height - $radius - 1, $diameter, $diameter, $fillcolor, 0, 12);
            //BL
            imageSmoothArc($mask, $width - $radius - 2, $height - $radius - 1, $diameter, $diameter, $fillcolor, 0, 12);
            //BR
            // Create an image object to hold the final image
            $rounded = imagecreatetruecolor($width, $height);
            imagealphablending($rounded, true);
            // Force to save as a PNG for transparency
            if ($params['forcepng']) {
                $imgType = IMAGETYPE_PNG;
            }
            // Create a background color
            if ($params['background'] || $imgType != IMAGETYPE_PNG) {
                $bg = $params['background'] ? $params['background'] : 'ffffff';
                $rgb = rgb_from_hex($bg);
                imagefill($rounded, 0, 0, imagecolorallocate($rounded, $rgb['r'], $rgb['g'], $rgb['b']));
            } else {
                imagefill($rounded, 0, 0, imagecolorallocatealpha($rounded, 255, 255, 255, 127));
                imagesavealpha($rounded, true);
            }
            // Cycle through the pixels and apply new color using mask
            for ($x = 0; $x < $width; $x++) {
                for ($y = 0; $y < $height; $y++) {
                    $rgb = imagecolorat($newImage, $x, $y);
                    $r = $rgb >> 16 & 0xff;
                    $g = $rgb >> 8 & 0xff;
                    $b = $rgb & 0xff;
                    $a = imagecolorsforindex($mask, imagecolorat($mask, $x, $y));
                    $a = $a['alpha'];
                    $color = imagecolorallocatealpha($rounded, $r, $g, $b, $a);
                    imagesetpixel($rounded, $x, $y, $color);
                }
            }
            $newImage = $rounded;
        }
        // Save the file
        switch ($imgType) {
            case IMAGETYPE_GIF:
                imagegif($newImage, $cachedPath);
                break;
            case IMAGETYPE_JPEG:
                imagejpeg($newImage, $cachedPath);
                break;
            case IMAGETYPE_PNG:
                imagepng($newImage, $cachedPath);
                break;
            default:
                return false;
        }
    }
    return $cachedUrl;
}