📄 phpthumb.filters.php
字号:
$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 MeanRemoval(&$gdimg) {
if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
if (ImageFilter($gdimg, IMG_FILTER_MEAN_REMOVAL)) {
return true;
}
$this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_MEAN_REMOVAL)', __FILE__, __LINE__);
// fall through and try it the hard way
}
// currently not implemented "the hard way"
$this->DebugMessage('FAILED: phpthumb_filters::MeanRemoval($gdimg) [function not implemented]', __FILE__, __LINE__);
return false;
}
function Negative(&$gdimg) {
if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
if (ImageFilter($gdimg, IMG_FILTER_NEGATE)) {
return true;
}
$this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_NEGATE)', __FILE__, __LINE__);
// fall through and try it the hard way
}
$ImageSX = ImageSX($gdimg);
$ImageSY = ImageSY($gdimg);
for ($x = 0; $x < $ImageSX; $x++) {
for ($y = 0; $y < $ImageSY; $y++) {
$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, (~$currentPixel['red'] & 0xFF), (~$currentPixel['green'] & 0xFF), (~$currentPixel['blue'] & 0xFF), $currentPixel['alpha']);
ImageSetPixel($gdimg, $x, $y, $newColor);
}
}
return true;
}
function RoundedImageCorners(&$gdimg, $radius_x, $radius_y) {
// generate mask at twice desired resolution and downsample afterwards for easy antialiasing
// mask is generated as a white double-size elipse on a triple-size black background and copy-paste-resampled
// onto a correct-size mask image as 4 corners due to errors when the entire mask is resampled at once (gray edges)
if ($gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction($radius_x * 6, $radius_y * 6)) {
if ($gdimg_cornermask = phpthumb_functions::ImageCreateFunction(ImageSX($gdimg), ImageSY($gdimg))) {
$color_transparent = ImageColorAllocate($gdimg_cornermask_triple, 255, 255, 255);
ImageFilledEllipse($gdimg_cornermask_triple, $radius_x * 3, $radius_y * 3, $radius_x * 4, $radius_y * 4, $color_transparent);
ImageFilledRectangle($gdimg_cornermask, 0, 0, ImageSX($gdimg), ImageSY($gdimg), $color_transparent);
ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, 0, 0, $radius_x, $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, 0, ImageSY($gdimg) - $radius_y, $radius_x, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, ImageSX($gdimg) - $radius_x, ImageSY($gdimg) - $radius_y, $radius_x * 3, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
ImageCopyResampled($gdimg_cornermask, $gdimg_cornermask_triple, ImageSX($gdimg) - $radius_x, 0, $radius_x * 3, $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
phpthumb_filters::ApplyMask($gdimg_cornermask, $gdimg);
ImageDestroy($gdimg_cornermask);
$this->DebugMessage('RoundedImageCorners('.$radius_x.', '.$radius_y.') succeeded', __FILE__, __LINE__);
return true;
} else {
$this->DebugMessage('FAILED: $gdimg_cornermask = phpthumb_functions::ImageCreateFunction('.ImageSX($gdimg).', '.ImageSY($gdimg).')', __FILE__, __LINE__);
}
ImageDestroy($gdimg_cornermask_triple);
} else {
$this->DebugMessage('FAILED: $gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction('.($radius_x * 6).', '.($radius_y * 6).')', __FILE__, __LINE__);
}
return false;
}
function Saturation(&$gdimg, $amount, $color='') {
if ($amount == 0) {
return true;
} elseif ($amount > 0) {
$amount = 0 - $amount;
} else {
$amount = abs($amount);
}
return phpthumb_filters::Desaturate($gdimg, $amount, $color);
}
function Sepia(&$gdimg, $amount, $targetColor) {
$amount = (is_numeric($amount) ? max(0, min(100, $amount)) : 50);
$targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'A28065');
if ($amount == 0) {
return true;
}
$TargetPixel['red'] = hexdec(substr($targetColor, 0, 2));
$TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
$TargetPixel['blue'] = hexdec(substr($targetColor, 4, 2));
$ImageSX = ImageSX($gdimg);
$ImageSY = ImageSY($gdimg);
for ($x = 0; $x < $ImageSX; $x++) {
for ($y = 0; $y < $ImageSY; $y++) {
$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
$GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
// http://www.gimpguru.org/Tutorials/SepiaToning/
// "In the traditional sepia toning process, the tinting occurs most in
// the mid-tones: the lighter and darker areas appear to be closer to B&W."
$SepiaAmount = ((128 - abs($GrayPixel['red'] - 128)) / 128) * ($amount / 100);
foreach ($TargetPixel as $key => $value) {
$NewPixel[$key] = round(max(0, min(255, $GrayPixel[$key] * (1 - $SepiaAmount) + ($TargetPixel[$key] * $SepiaAmount))));
}
$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
ImageSetPixel($gdimg, $x, $y, $newColor);
}
}
return true;
}
function Smooth(&$gdimg, $amount=6) {
$amount = min(25, max(0, $amount));
if ($amount == 0) {
return true;
}
if (phpthumb_functions::version_compare_replacement(phpversion(), '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
if (ImageFilter($gdimg, IMG_FILTER_SMOOTH, $amount)) {
return true;
}
$this->DebugMessage('FAILED: ImageFilter($gdimg, IMG_FILTER_SMOOTH, '.$amount.')', __FILE__, __LINE__);
// fall through and try it the hard way
}
// currently not implemented "the hard way"
$this->DebugMessage('FAILED: phpthumb_filters::Smooth($gdimg, '.$amount.') [function not implemented]', __FILE__, __LINE__);
return false;
}
function Threshold(&$gdimg, $cutoff) {
$cutoff = min(255, max(0, ($cutoff ? $cutoff : 128)));
for ($x = 0; $x < ImageSX($gdimg); $x++) {
for ($y = 0; $y < ImageSY($gdimg); $y++) {
$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
$grayPixel = phpthumb_functions::GrayscalePixel($currentPixel);
if ($grayPixel['red'] < $cutoff) {
$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0x00, 0x00, 0x00, $currentPixel['alpha']);
} else {
$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0xFF, 0xFF, 0xFF, $currentPixel['alpha']);
}
ImageSetPixel($gdimg, $x, $y, $newColor);
}
}
return true;
}
function ImageTrueColorToPalette2(&$image, $dither, $ncolors) {
// http://www.php.net/manual/en/function.imagetruecolortopalette.php
// zmorris at zsculpt dot com (17-Aug-2004 06:58)
$width = ImageSX($image);
$height = ImageSY($image);
$image_copy = ImageCreateTrueColor($width, $height);
//ImageCopyMerge($image_copy, $image, 0, 0, 0, 0, $width, $height, 100);
ImageCopy($image_copy, $image, 0, 0, 0, 0, $width, $height);
ImageTrueColorToPalette($image, $dither, $ncolors);
ImageColorMatch($image_copy, $image);
ImageDestroy($image_copy);
return true;
}
function ReduceColorDepth(&$gdimg, $colors=256, $dither=true) {
$colors = max(min($colors, 256), 2);
// ImageTrueColorToPalette usually makes ugly colors, the replacement is a bit better
//ImageTrueColorToPalette($gdimg, $dither, $colors);
phpthumb_filters::ImageTrueColorToPalette2($gdimg, $dither, $colors);
return true;
}
function WhiteBalance(&$gdimg, $targetColor='') {
if (phpthumb_functions::IsHexColor($targetColor)) {
$targetPixel = array(
'red' => hexdec(substr($targetColor, 0, 2)),
'green' => hexdec(substr($targetColor, 2, 2)),
'blue' => hexdec(substr($targetColor, 4, 2))
);
} else {
$Analysis = phpthumb_filters::HistogramAnalysis($gdimg, false);
$targetPixel = array(
'red' => max(array_keys($Analysis['red'])),
'green' => max(array_keys($Analysis['green'])),
'blue' => max(array_keys($Analysis['blue']))
);
}
$grayValue = phpthumb_functions::GrayscaleValue($targetPixel['red'], $targetPixel['green'], $targetPixel['blue']);
$scaleR = $grayValue / $targetPixel['red'];
$scaleG = $grayValue / $targetPixel['green'];
$scaleB = $grayValue / $targetPixel['blue'];
for ($x = 0; $x < ImageSX($gdimg); $x++) {
for ($y = 0; $y < ImageSY($gdimg); $y++) {
$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe(
$gdimg,
max(0, min(255, round($currentPixel['red'] * $scaleR))),
max(0, min(255, round($currentPixel['green'] * $scaleG))),
max(0, min(255, round($currentPixel['blue'] * $scaleB))),
$currentPixel['alpha']
);
ImageSetPixel($gdimg, $x, $y, $newColor);
}
}
return true;
}
function WatermarkText(&$gdimg, $text, $size, $alignment, $hex_color='000000', $ttffont='', $opacity=100, $margin=5, $angle=0) {
// text watermark requested
if (!$text) {
return false;
}
ImageAlphaBlending($gdimg, true);
$text = str_replace("\r\n", "\n", $text);
$text = str_replace("\r", "\n", $text);
$textlines = explode("\n", $text);
if (@is_readable($ttffont) && is_file($ttffont)) {
$opacity = 100 - intval(max(min($opacity, 100), 0));
$this->DebugMessage('Using TTF font "'.$ttffont.'"', __FILE__, __LINE__);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -