function ImageBorder(&$gdimg, $border_width, $radius_x, $radius_y, $hexcolor_border) { $border_width = $border_width ? $border_width : 1; $radius_x = $radius_x ? $radius_x : 0; $radius_y = $radius_y ? $radius_y : 0; $output_width = ImageSX($gdimg); $output_height = ImageSY($gdimg); list($new_width, $new_height) = phpthumb_functions::ProportionalResize($output_width, $output_height, $output_width - max($border_width * 2, $radius_x), $output_height - max($border_width * 2, $radius_y)); $offset_x = $radius_x ? $output_width - $new_width - $radius_x : 0; $offset_y = $radius_y ? $output_height - $new_height - $radius_y : 0; if ($gd_border_canvas = phpthumb_functions::ImageCreateFunction($output_width, $output_height)) { if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=')) { ImageSaveAlpha($gd_border_canvas, true); } ImageAlphaBlending($gd_border_canvas, false); $color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gd_border_canvas, 255, 255, 255, 127); ImageFilledRectangle($gd_border_canvas, 0, 0, $output_width, $output_height, $color_background); $color_border = phpthumb_functions::ImageHexColorAllocate($gd_border_canvas, phpthumb_functions::IsHexColor($hexcolor_border) ? $hexcolor_border : '000000'); for ($i = 0; $i < $border_width; $i++) { ImageLine($gd_border_canvas, floor($offset_x / 2) + $radius_x, $i, $output_width - $radius_x - ceil($offset_x / 2), $i, $color_border); // top ImageLine($gd_border_canvas, floor($offset_x / 2) + $radius_x, $output_height - 1 - $i, $output_width - $radius_x - ceil($offset_x / 2), $output_height - 1 - $i, $color_border); // bottom ImageLine($gd_border_canvas, floor($offset_x / 2) + $i, $radius_y, floor($offset_x / 2) + $i, $output_height - $radius_y, $color_border); // left ImageLine($gd_border_canvas, $output_width - 1 - $i - ceil($offset_x / 2), $radius_y, $output_width - 1 - $i - ceil($offset_x / 2), $output_height - $radius_y, $color_border); // right } if ($radius_x && $radius_y) { // PHP bug: ImageArc() with thicknesses > 1 give bad/undesirable/unpredicatable results // Solution: Draw multiple 1px arcs side-by-side. // Problem: parallel arcs give strange/ugly antialiasing problems // Solution: draw non-parallel arcs, from one side of the line thickness at the start angle // to the opposite edge of the line thickness at the terminating angle for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) { ImageArc($gd_border_canvas, floor($offset_x / 2) + 1 + $radius_x, $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left ImageArc($gd_border_canvas, $output_width - $radius_x - 1 - ceil($offset_x / 2), $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right ImageArc($gd_border_canvas, $output_width - $radius_x - 1 - ceil($offset_x / 2), $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2, 0, 90, $color_border); // bottom-right ImageArc($gd_border_canvas, floor($offset_x / 2) + 1 + $radius_x, $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2, 90, 180, $color_border); // bottom-left } if ($border_width > 1) { for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) { ImageArc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x, $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left ImageArc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2), $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right ImageArc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2), $output_height - $radius_y, $radius_x * 2, $radius_y * 2, 0, 90, $color_border); // bottom-right ImageArc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x, $output_height - $radius_y, $radius_x * 2, $radius_y * 2, 90, 180, $color_border); // bottom-left } } } phpthumb_functions::ImageResizeFunction($gd_border_canvas, $gdimg, floor(($output_width - $new_width) / 2), round(($output_height - $new_height) / 2), 0, 0, $new_width, $new_height, $output_width, $output_height); ImageDestroy($gdimg); $gdimg = phpthumb_functions::ImageCreateFunction($output_width, $output_height); if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=')) { ImageSaveAlpha($gdimg, true); } ImageAlphaBlending($gdimg, false); $gdimg_color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 255, 255, 255, 127); ImageFilledRectangle($gdimg, 0, 0, $output_width, $output_height, $gdimg_color_background); ImageCopy($gdimg, $gd_border_canvas, 0, 0, 0, 0, $output_width, $output_height); //$gdimg = $gd_border_canvas; ImageDestroy($gd_border_canvas); return true; } else { $this->DebugMessage('FAILED: $gd_border_canvas = phpthumb_functions::ImageCreateFunction(' . $output_width . ', ' . $output_height . ')', __FILE__, __LINE__); } return false; }
function ApplyFilters() { if ($this->fltr && is_array($this->fltr)) { if (!(include_once dirname(__FILE__) . '/phpthumb.filters.php')) { $this->DebugMessage('Error including "' . dirname(__FILE__) . '/phpthumb.filters.php" which is required for applying filters (' . implode(';', $this->fltr) . ')', __FILE__, __LINE__); return false; } foreach ($this->fltr as $filtercommand) { @(list($command, $parameter) = explode('|', $filtercommand, 2)); $this->DebugMessage('Attempting to process filter command "' . $command . '"', __FILE__, __LINE__); switch ($command) { case 'brit': phpthumb_filters::Brightness($this->gdimg_output, $parameter); break; case 'cont': phpthumb_filters::Contrast($this->gdimg_output, $parameter); break; case 'ds': phpthumb_filters::Desaturate($this->gdimg_output, $parameter, ''); break; case 'sat': phpthumb_filters::Saturation($this->gdimg_output, $parameter, ''); break; case 'gray': phpthumb_filters::Grayscale($this->gdimg_output); break; case 'clr': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping Colorize() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); break; } @(list($amount, $color) = explode('|', $parameter)); phpthumb_filters::Colorize($this->gdimg_output, $amount, $color); break; case 'sep': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping Sepia() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); break; } @(list($amount, $color) = explode('|', $parameter)); phpthumb_filters::Sepia($this->gdimg_output, $amount, $color); break; case 'gam': phpthumb_filters::Gamma($this->gdimg_output, $parameter); break; case 'neg': phpthumb_filters::Negative($this->gdimg_output); break; case 'th': phpthumb_filters::Threshold($this->gdimg_output, $parameter); break; case 'rcd': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping ReduceColorDepth() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); break; } @(list($colors, $dither) = explode('|', $parameter)); $colors = $colors ? (int) $colors : 256; $dither = strlen($dither) > 0 ? (bool) $dither : true; phpthumb_filters::ReduceColorDepth($this->gdimg_output, $colors, $dither); break; case 'flip': phpthumb_filters::Flip($this->gdimg_output, strpos(strtolower($parameter), 'x') !== false, strpos(strtolower($parameter), 'y') !== false); break; case 'edge': phpthumb_filters::EdgeDetect($this->gdimg_output); break; case 'emb': phpthumb_filters::Emboss($this->gdimg_output); break; case 'bvl': @(list($width, $color1, $color2) = explode('|', $parameter)); phpthumb_filters::Bevel($this->gdimg_output, $width, $color1, $color2); break; case 'lvl': @(list($band, $min, $max) = explode('|', $parameter)); $band = $band ? $band : '*'; $min = strlen($min) > 0 ? $min : '-1'; $max = strlen($max) > 0 ? $max : '-1'; phpthumb_filters::HistogramStretch($this->gdimg_output, $band, $min, $max); break; case 'wb': phpthumb_filters::WhiteBalance($this->gdimg_output, $parameter); break; case 'hist': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping HistogramOverlay() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); break; } @(list($bands, $colors, $width, $height, $alignment, $opacity, $margin) = explode('|', $parameter)); $bands = $bands ? $bands : '*'; $colors = $colors ? $colors : ''; $width = $width ? $width : 0.25; $height = $height ? $height : 0.25; $alignment = $alignment ? $alignment : 'BR'; $opacity = $opacity ? $opacity : 50; $margin = $margin ? $margin : 5; phpthumb_filters::HistogramOverlay($this->gdimg_output, $bands, $colors, $width, $height, $alignment, $opacity, $margin); break; case 'fram': @(list($frame_width, $edge_width, $color_frame, $color1, $color2) = explode('|', $parameter)); phpthumb_filters::Frame($this->gdimg_output, $frame_width, $edge_width, $color_frame, $color1, $color2); break; case 'drop': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping DropShadow() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); return false; } $this->is_alpha = true; @(list($distance, $width, $color, $angle, $fade) = explode('|', $parameter)); phpthumb_filters::DropShadow($this->gdimg_output, $distance, $width, $color, $angle, $fade); break; case 'mask': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping Mask() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); return false; } $mask_filename = $this->ResolveFilenameToAbsolute($parameter); if (@is_readable($mask_filename) && ($fp_mask = @fopen($mask_filename, 'rb'))) { $MaskImageData = fread($fp_mask, filesize($mask_filename)); fclose($fp_mask); if ($gdimg_mask = $this->ImageCreateFromStringReplacement($MaskImageData)) { $this->is_alpha = true; phpthumb_filters::ApplyMask($gdimg_mask, $this->gdimg_output); ImageDestroy($gdimg_mask); } else { $this->DebugMessage('ImageCreateFromStringReplacement() failed for "' . $mask_filename . '"', __FILE__, __LINE__); } } else { $this->DebugMessage('Cannot open mask file "' . $mask_filename . '"', __FILE__, __LINE__); } break; case 'elip': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping Elipse() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); return false; } $this->is_alpha = true; phpthumb_filters::Elipse($this->gdimg_output); break; case 'ric': if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping RoundedImageCorners() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); return false; } @(list($radius_x, $radius_y) = explode('|', $parameter)); if ($radius_x < 1 || $radius_y < 1) { $this->DebugMessage('Skipping RoundedImageCorners(' . $radius_x . ', ' . $radius_y . ') because x/y radius is less than 1', __FILE__, __LINE__); break; } $this->is_alpha = true; phpthumb_filters::RoundedImageCorners($this->gdimg_output, $radius_x, $radius_y); break; case 'bord': @(list($border_width, $radius_x, $radius_y, $hexcolor_border) = explode('|', $parameter)); $this->is_alpha = true; phpthumb_filters::ImageBorder($this->gdimg_output, $border_width, $radius_x, $radius_y, $hexcolor_border); break; case 'over': @(list($filename, $underlay, $margin, $opacity) = explode('|', $parameter)); $underlay = (bool) ($underlay ? $underlay : false); $margin = strlen($margin) > 0 ? $margin : ($underlay ? 0.1 : 0.0); $opacity = strlen($opacity) > 0 ? $opacity : 100; if ($margin > 0 && $margin < 1) { $margin = min(0.499, $margin); } elseif ($margin > -1 && $margin < 0) { $margin = max(-0.499, $margin); } $filename = $this->ResolveFilenameToAbsolute($filename); if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) { $WatermarkImageData = fread($fp_watermark, filesize($filename)); fclose($fp_watermark); if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) { if ($margin < 1) { $resized_x = max(1, ImageSX($this->gdimg_output) - round(2 * (ImageSX($this->gdimg_output) * $margin))); $resized_y = max(1, ImageSY($this->gdimg_output) - round(2 * (ImageSY($this->gdimg_output) * $margin))); } else { $resized_x = max(1, ImageSX($this->gdimg_output) - round(2 * $margin)); $resized_y = max(1, ImageSY($this->gdimg_output) - round(2 * $margin)); } if ($underlay) { if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction(ImageSX($this->gdimg_output), ImageSY($this->gdimg_output))) { ImageAlphaBlending($img_watermark_resized, false); ImageSaveAlpha($img_watermark_resized, true); phpthumb_functions::ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, ImageSX($img_watermark_resized), ImageSY($img_watermark_resized), ImageSX($img_watermark), ImageSY($img_watermark)); if ($img_source_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) { ImageAlphaBlending($img_source_resized, false); ImageSaveAlpha($img_source_resized, true); phpthumb_functions::ImageResizeFunction($img_source_resized, $this->gdimg_output, 0, 0, 0, 0, ImageSX($img_source_resized), ImageSY($img_source_resized), ImageSX($this->gdimg_output), ImageSY($this->gdimg_output)); phpthumb_filters::WatermarkOverlay($img_watermark_resized, $img_source_resized, 'C', $opacity, $margin); ImageCopy($this->gdimg_output, $img_watermark_resized, 0, 0, 0, 0, ImageSX($this->gdimg_output), ImageSY($this->gdimg_output)); } else { $this->DebugMessage('phpthumb_functions::ImageCreateFunction(' . $resized_x . ', ' . $resized_y . ')', __FILE__, __LINE__); } ImageDestroy($img_watermark_resized); } else { $this->DebugMessage('phpthumb_functions::ImageCreateFunction(' . ImageSX($this->gdimg_output) . ', ' . ImageSY($this->gdimg_output) . ')', __FILE__, __LINE__); } } else { // overlay if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) { ImageAlphaBlending($img_watermark_resized, false); ImageSaveAlpha($img_watermark_resized, true); phpthumb_functions::ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, ImageSX($img_watermark_resized), ImageSY($img_watermark_resized), ImageSX($img_watermark), ImageSY($img_watermark)); phpthumb_filters::WatermarkOverlay($this->gdimg_output, $img_watermark_resized, 'C', $opacity, $margin); ImageDestroy($img_watermark_resized); } else { $this->DebugMessage('phpthumb_functions::ImageCreateFunction(' . $resized_x . ', ' . $resized_y . ')', __FILE__, __LINE__); } } ImageDestroy($img_watermark); } else { $this->DebugMessage('ImageCreateFromStringReplacement() failed for "' . $filename . '"', __FILE__, __LINE__); } } else { $this->DebugMessage('Cannot open overlay file "' . $filename . '"', __FILE__, __LINE__); } break; case 'wmi': @(list($filename, $alignment, $opacity, $margin) = explode('|', $parameter)); $alignment = $alignment ? $alignment : 'BR'; $opacity = strlen($opacity) ? $opacity : 50; $margin = strlen($margin) ? $margin : 5; $filename = $this->ResolveFilenameToAbsolute($filename); if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) { $WatermarkImageData = fread($fp_watermark, filesize($filename)); fclose($fp_watermark); if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) { // great phpthumb_filters::WatermarkOverlay($this->gdimg_output, $img_watermark, $alignment, $opacity, $margin); ImageDestroy($img_watermark); } else { $this->DebugMessage('ImageCreateFromStringReplacement() failed for "' . $filename . '"', __FILE__, __LINE__); } } else { $this->DebugMessage('Cannot open watermark file "' . $filename . '"', __FILE__, __LINE__); } break; case 'wmt': @(list($text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle) = explode('|', $parameter)); $text = $text ? $text : ''; $size = $size ? $size : 3; $alignment = $alignment ? $alignment : 'BR'; $hex_color = $hex_color ? $hex_color : '000000'; $ttffont = $ttffont ? $ttffont : ''; $opacity = strlen($opacity) ? $opacity : 50; $margin = strlen($margin) ? $margin : 5; $angle = strlen($angle) ? $angle : 0; if (basename($ttffont) == $ttffont) { $ttffont = realpath($this->config_ttf_directory . $this->osslash . $ttffont); } else { $ttffont = $this->ResolveFilenameToAbsolute($ttffont); } phpthumb_filters::WatermarkText($this->gdimg_output, $text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle); break; case 'blur': @(list($radius) = explode('|', $parameter)); $radius = $radius ? $radius : 1; if (phpthumb_functions::gd_version() < 2) { $this->DebugMessage('Skipping Blur() because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); return false; } phpthumb_filters::Blur($this->gdimg_output, $radius); break; case 'gblr': phpthumb_filters::BlurGaussian($this->gdimg_output); break; case 'sblr': phpthumb_filters::BlurSelective($this->gdimg_output); break; case 'mean': phpthumb_filters::MeanRemoval($this->gdimg_output); break; case 'smth': phpthumb_filters::Smooth($this->gdimg_output, $parameter); break; case 'usm': @(list($amount, $radius, $threshold) = explode('|', $parameter)); $amount = $amount ? $amount : 80; $radius = $radius ? $radius : 0.5; $threshold = strlen($threshold) ? $threshold : 3; if (phpthumb_functions::gd_version() >= 2.0) { ob_start(); if (!@(include_once dirname(__FILE__) . '/phpthumb.unsharp.php')) { $include_error = ob_get_contents(); if ($include_error) { $this->DebugMessage('include_once("' . dirname(__FILE__) . '/phpthumb.unsharp.php") generated message: "' . $include_error . '"', __FILE__, __LINE__); } ob_end_clean(); $this->DebugMessage('Error including "' . dirname(__FILE__) . '/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__); return false; } ob_end_clean(); phpUnsharpMask::applyUnsharpMask($this->gdimg_output, $amount, $radius, $threshold); } else { $this->DebugMessage('Skipping unsharp mask because gd_version is "' . phpthumb_functions::gd_version() . '"', __FILE__, __LINE__); return false; } break; } } } return true; }