function ImageMagickThumbnailToGD() { // http://www.imagemagick.org/script/command-line-options.php $this->useRawIMoutput = true; if (phpthumb_functions::gd_version()) { // if GD is not available, must use whatever ImageMagick can output // $UnAllowedParameters contains options that can only be processed in GD, not ImageMagick // note: 'fltr' *may* need to be processed by GD, but we'll check that in more detail below $UnAllowedParameters = array('xto', 'ar', 'bg', 'bc'); // 'ra' may be part of this list, if not a multiple of 90� foreach ($UnAllowedParameters as $parameter) { if (isset($this->{$parameter})) { $this->DebugMessage('$this->useRawIMoutput=false because "' . $parameter . '" is set', __FILE__, __LINE__); $this->useRawIMoutput = false; break; } } } $this->DebugMessage('$this->useRawIMoutput=' . ($this->useRawIMoutput ? 'true' : 'false') . ' after checking $UnAllowedParameters', __FILE__, __LINE__); $outputFormat = $this->thumbnailFormat; if (phpthumb_functions::gd_version()) { if ($this->useRawIMoutput) { switch ($this->thumbnailFormat) { case 'gif': $ImageCreateFunction = 'ImageCreateFromGIF'; $this->is_alpha = true; break; case 'png': $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; break; case 'jpg': case 'jpeg': $ImageCreateFunction = 'ImageCreateFromJPEG'; break; default: $this->DebugMessage('Forcing output to PNG because $this->thumbnailFormat (' . $this->thumbnailFormat . ' is not a GD-supported format)', __FILE__, __LINE__); $outputFormat = 'png'; $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; $this->useRawIMoutput = false; break; } if (!function_exists(@$ImageCreateFunction)) { // ImageMagickThumbnailToGD() depends on ImageCreateFromPNG/ImageCreateFromGIF //$this->DebugMessage('ImageMagickThumbnailToGD() aborting because '.@$ImageCreateFunction.'() is not available', __FILE__, __LINE__); $this->useRawIMoutput = true; //return false; } } else { $outputFormat = 'png'; $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; $this->useRawIMoutput = false; } } // http://freealter.org/doc_distrib/ImageMagick-5.1.1/www/convert.html if (!$this->sourceFilename && $this->rawImageData) { $this->SourceDataToTempFile(); } if (!$this->sourceFilename) { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty', __FILE__, __LINE__); $this->useRawIMoutput = false; return false; } if ($this->issafemode) { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__); $this->useRawIMoutput = false; return false; } // TO BE FIXED //if (true) { // $this->DebugMessage('ImageMagickThumbnailToGD() aborting it is broken right now', __FILE__, __LINE__); // $this->useRawIMoutput = false; // return false; //} $commandline = $this->ImageMagickCommandlineBase(); if ($commandline) { if ($IMtempfilename = $this->phpThumb_tempnam()) { $IMtempfilename = realpath($IMtempfilename); $IMuseExplicitImageOutputDimensions = false; if ($this->ImageMagickSwitchAvailable('thumbnail') && $this->config_imagemagick_use_thumbnail) { $IMresizeParameter = 'thumbnail'; } else { $IMresizeParameter = 'resize'; // some (older? around 2002) versions of IM won't accept "-resize 100x" but require "-resize 100x100" $commandline_test = $this->ImageMagickCommandlineBase() . ' logo: -resize 1x ' . escapeshellarg($IMtempfilename) . ' 2>&1'; $IMresult_test = phpthumb_functions::SafeExec($commandline_test); $IMuseExplicitImageOutputDimensions = preg_match('#image dimensions are zero#i', $IMresult_test); $this->DebugMessage('IMuseExplicitImageOutputDimensions = ' . intval($IMuseExplicitImageOutputDimensions), __FILE__, __LINE__); if ($fp_im_temp = @fopen($IMtempfilename, 'wb')) { // erase temp image so ImageMagick logo doesn't get output if other processing fails fclose($fp_im_temp); } } if (!is_null($this->dpi) && $this->ImageMagickSwitchAvailable('density')) { // for raster source formats only (WMF, PDF, etc) $commandline .= ' -density ' . escapeshellarg($this->dpi); } ob_start(); $getimagesize = GetImageSize($this->sourceFilename); $GetImageSizeError = ob_get_contents(); ob_end_clean(); if (is_array($getimagesize)) { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') SUCCEEDED: ' . print_r($getimagesize, true), __FILE__, __LINE__); } else { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') FAILED with error "' . $GetImageSizeError . '"', __FILE__, __LINE__); } if (is_array($getimagesize)) { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') returned [w=' . $getimagesize[0] . ';h=' . $getimagesize[1] . ';f=' . $getimagesize[2] . ']', __FILE__, __LINE__); $this->source_width = $getimagesize[0]; $this->source_height = $getimagesize[1]; $this->DebugMessage('source dimensions set to ' . $this->source_width . 'x' . $this->source_height, __FILE__, __LINE__); $this->SetOrientationDependantWidthHeight(); if (!preg_match('#(' . implode('|', $this->AlphaCapableFormats) . ')#i', $outputFormat)) { // not a transparency-capable format $commandline .= ' -background ' . escapeshellarg('#' . ($this->bg ? $this->bg : 'FFFFFF')); if ($getimagesize[2] == IMAGETYPE_GIF) { $commandline .= ' -flatten'; } } if ($getimagesize[2] == IMAGETYPE_GIF) { $commandline .= ' -coalesce'; // may be needed for animated GIFs } if ($this->source_width || $this->source_height) { if ($this->zc) { $borderThickness = 0; if (!empty($this->fltr)) { foreach ($this->fltr as $key => $value) { if (preg_match('#^bord\\|([0-9]+)#', $value, $matches)) { $borderThickness = $matches[1]; break; } } } $wAll = intval(max($this->w, $this->wp, $this->wl, $this->ws)) - 2 * $borderThickness; $hAll = intval(max($this->h, $this->hp, $this->hl, $this->hs)) - 2 * $borderThickness; $imAR = $this->source_width / $this->source_height; $zcAR = $wAll && $hAll ? $wAll / $hAll : 1; $side = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll)); $sideX = phpthumb_functions::nonempty_min($this->source_width, $wAll, round($hAll * $zcAR)); $sideY = phpthumb_functions::nonempty_min($this->source_height, $hAll, round($wAll / $zcAR)); $thumbnailH = round(max($sideY, $sideY * $zcAR / $imAR)); $commandline .= ' -' . $IMresizeParameter . ' ' . escapeshellarg(($IMuseExplicitImageOutputDimensions ? $thumbnailH : '') . 'x' . $thumbnailH); switch (strtoupper($this->zc)) { case 'T': $commandline .= ' -gravity north'; break; case 'B': $commandline .= ' -gravity south'; break; case 'L': $commandline .= ' -gravity west'; break; case 'R': $commandline .= ' -gravity east'; break; case 'TL': $commandline .= ' -gravity northwest'; break; case 'TR': $commandline .= ' -gravity northeast'; break; case 'BL': $commandline .= ' -gravity southwest'; break; case 'BR': $commandline .= ' -gravity southeast'; break; case '1': case 'C': default: $commandline .= ' -gravity center'; break; } if ($wAll > 0 && $hAll > 0) { $commandline .= ' -crop ' . escapeshellarg($wAll . 'x' . $hAll . '+0+0'); } else { $commandline .= ' -crop ' . escapeshellarg($side . 'x' . $side . '+0+0'); } if ($this->ImageMagickSwitchAvailable('repage')) { $commandline .= ' +repage'; } else { $this->DebugMessage('Skipping "+repage" because ImageMagick (v' . $this->ImageMagickVersion() . ') does not support it', __FILE__, __LINE__); } } elseif ($this->sw || $this->sh || $this->sx || $this->sy) { $crop_param = ''; $crop_param .= $this->sw ? $this->sw < 2 ? round($this->sw * $this->source_width) : $this->sw : $this->source_width; $crop_param .= 'x' . ($this->sh ? $this->sh < 2 ? round($this->sh * $this->source_height) : $this->sh : $this->source_height); $crop_param .= '+' . ($this->sx < 2 ? round($this->sx * $this->source_width) : $this->sx); $crop_param .= '+' . ($this->sy < 2 ? round($this->sy * $this->source_height) : $this->sy); // TO BE FIXED // makes 1x1 output // http://trainspotted.com/phpThumb/phpThumb.php?src=/content/CNR/47/CNR-4728-LD-L-20110723-898.jpg&w=100&h=100&far=1&f=png&fltr[]=lvl&sx=0.05&sy=0.25&sw=0.92&sh=0.42 // '/usr/bin/convert' -density 150 -thumbnail 100x100 -contrast-stretch '0.1%' '/var/www/vhosts/trainspotted.com/httpdocs/content/CNR/47/CNR-4728-LD-L-20110723-898.jpg[0]' png:'/var/www/vhosts/trainspotted.com/httpdocs/phpThumb/_cache/pThumbIIUlvj' // $commandline .= ' -crop '.escapeshellarg($crop_param); // this is broken for aoe=1, but unsure how to fix. Send advice to info@silisoftware.com if ($this->w || $this->h) { //if ($this->ImageMagickSwitchAvailable('repage')) { if (false) { // TO BE FIXED // newer versions of ImageMagick require -repage <geometry> $commandline .= ' -repage'; } else { $this->DebugMessage('Skipping "-repage" because ImageMagick (v' . $this->ImageMagickVersion() . ') does not support it', __FILE__, __LINE__); } if ($IMuseExplicitImageOutputDimensions) { if ($this->w && !$this->h) { $this->h = ceil($this->w / ($this->source_width / $this->source_height)); } elseif ($this->h && !$this->w) { $this->w = ceil($this->h * ($this->source_width / $this->source_height)); } } $commandline .= ' -' . $IMresizeParameter . ' ' . escapeshellarg($this->w . 'x' . $this->h); } } else { if ($this->iar && intval($this->w) > 0 && intval($this->h) > 0) { list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra); $nw = round($nw) != 0 ? round($nw) : ''; $nh = round($nh) != 0 ? round($nh) : ''; $commandline .= ' -' . $IMresizeParameter . ' ' . escapeshellarg($nw . 'x' . $nh . '!'); } else { $this->w = ($this->aoe || $this->far) && $this->w ? $this->w : ($this->w ? phpthumb_functions::nonempty_min($this->w, $getimagesize[0]) : ''); $this->h = ($this->aoe || $this->far) && $this->h ? $this->h : ($this->h ? phpthumb_functions::nonempty_min($this->h, $getimagesize[1]) : ''); if ($this->w || $this->h) { if ($IMuseExplicitImageOutputDimensions) { if ($this->w && !$this->h) { $this->h = ceil($this->w / ($this->source_width / $this->source_height)); } elseif ($this->h && !$this->w) { $this->w = ceil($this->h * ($this->source_width / $this->source_height)); } } list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra); $nw = round($nw) != 0 ? round($nw) : ''; $nh = round($nh) != 0 ? round($nh) : ''; $commandline .= ' -' . $IMresizeParameter . ' ' . escapeshellarg($nw . 'x' . $nh); } } } } } else { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') failed', __FILE__, __LINE__); if ($this->w || $this->h) { $exactDimensionsBang = $this->iar && intval($this->w) > 0 && intval($this->h) > 0 ? '!' : ''; if ($IMuseExplicitImageOutputDimensions) { // unknown source aspect ratio, just put large number and hope IM figures it out $commandline .= ' -' . $IMresizeParameter . ' ' . escapeshellarg(($this->w ? $this->w : '9999') . 'x' . ($this->h ? $this->h : '9999') . $exactDimensionsBang); } else { $commandline .= ' -' . $IMresizeParameter . ' ' . escapeshellarg($this->w . 'x' . $this->h . $exactDimensionsBang); } } } if ($this->ra) { $this->ra = intval($this->ra); if ($this->ImageMagickSwitchAvailable('rotate')) { if (!preg_match('#(' . implode('|', $this->AlphaCapableFormats) . ')#i', $outputFormat) || phpthumb_functions::version_compare_replacement($this->ImageMagickVersion(), '6.3.7', '>=')) { $this->DebugMessage('Using ImageMagick rotate', __FILE__, __LINE__); $commandline .= ' -rotate ' . escapeshellarg($this->ra); if ($this->ra % 90 != 0) { if (preg_match('#(' . implode('|', $this->AlphaCapableFormats) . ')#i', $outputFormat)) { // alpha-capable format $commandline .= ' -background rgba(255,255,255,0)'; } else { $commandline .= ' -background ' . escapeshellarg('#' . ($this->bg ? $this->bg : 'FFFFFF')); } } $this->ra = 0; } else { $this->DebugMessage('Not using ImageMagick rotate because alpha background buggy before v6.3.7', __FILE__, __LINE__); } } else { $this->DebugMessage('Not using ImageMagick rotate because not supported', __FILE__, __LINE__); } } $successfullyProcessedFilters = array(); foreach ($this->fltr as $filterkey => $filtercommand) { @(list($command, $parameter) = explode('|', $filtercommand, 2)); switch ($command) { case 'brit': if ($this->ImageMagickSwitchAvailable('modulate')) { $commandline .= ' -modulate ' . escapeshellarg(100 + intval($parameter) . ',100,100'); $successfullyProcessedFilters[] = $filterkey; } break; case 'cont': if ($this->ImageMagickSwitchAvailable('contrast')) { $contDiv10 = round(intval($parameter) / 10); if ($contDiv10 > 0) { $contDiv10 = min($contDiv10, 100); for ($i = 0; $i < $contDiv10; $i++) { $commandline .= ' -contrast'; // increase contrast by 10% } } elseif ($contDiv10 < 0) { $contDiv10 = max($contDiv10, -100); for ($i = $contDiv10; $i < 0; $i++) { $commandline .= ' +contrast'; // decrease contrast by 10% } } else { // do nothing } $successfullyProcessedFilters[] = $filterkey; } break; case 'ds': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { if ($parameter == 100) { $commandline .= ' -colorspace GRAY'; $commandline .= ' -modulate 100,0,100'; } else { $commandline .= ' -modulate ' . escapeshellarg('100,' . (100 - intval($parameter)) . ',100'); } $successfullyProcessedFilters[] = $filterkey; } break; case 'sat': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { if ($parameter == -100) { $commandline .= ' -colorspace GRAY'; $commandline .= ' -modulate 100,0,100'; } else { $commandline .= ' -modulate ' . escapeshellarg('100,' . (100 + intval($parameter)) . ',100'); } $successfullyProcessedFilters[] = $filterkey; } break; case 'gray': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { $commandline .= ' -colorspace GRAY'; $commandline .= ' -modulate 100,0,100'; $successfullyProcessedFilters[] = $filterkey; } break; case 'clr': if ($this->ImageMagickSwitchAvailable(array('fill', 'colorize'))) { @(list($amount, $color) = explode('|', $parameter)); $commandline .= ' -fill ' . escapeshellarg('#' . preg_replace('#[^0-9A-F]#i', '', $color)); $commandline .= ' -colorize ' . escapeshellarg(min(max(intval($amount), 0), 100)); } break; case 'sep': if ($this->ImageMagickSwitchAvailable('sepia-tone')) { @(list($amount, $color) = explode('|', $parameter)); $amount = $amount ? $amount : 80; if (!$color) { $commandline .= ' -sepia-tone ' . escapeshellarg(min(max(intval($amount), 0), 100) . '%'); $successfullyProcessedFilters[] = $filterkey; } } break; case 'gam': @(list($amount) = explode('|', $parameter)); $amount = min(max(floatval($amount), 0.001), 10); if (number_format($amount, 3) != '1.000') { if ($this->ImageMagickSwitchAvailable('gamma')) { $commandline .= ' -gamma ' . escapeshellarg($amount); $successfullyProcessedFilters[] = $filterkey; } } break; case 'neg': if ($this->ImageMagickSwitchAvailable('negate')) { $commandline .= ' -negate'; $successfullyProcessedFilters[] = $filterkey; } break; case 'th': @(list($amount) = explode('|', $parameter)); if ($this->ImageMagickSwitchAvailable(array('threshold', 'dither', 'monochrome'))) { $commandline .= ' -threshold ' . escapeshellarg(round(min(max(intval($amount), 0), 255) / 2.55) . '%'); $commandline .= ' -dither'; $commandline .= ' -monochrome'; $successfullyProcessedFilters[] = $filterkey; } break; case 'rcd': if ($this->ImageMagickSwitchAvailable(array('colors', 'dither'))) { @(list($colors, $dither) = explode('|', $parameter)); $colors = $colors ? (int) $colors : 256; $dither = strlen($dither) > 0 ? (bool) $dither : true; $commandline .= ' -colors ' . escapeshellarg(max($colors, 8)); // ImageMagick will otherwise fail with "cannot quantize to fewer than 8 colors" $commandline .= $dither ? ' -dither' : ' +dither'; $successfullyProcessedFilters[] = $filterkey; } break; case 'flip': if ($this->ImageMagickSwitchAvailable(array('flip', 'flop'))) { if (strpos(strtolower($parameter), 'x') !== false) { $commandline .= ' -flop'; } if (strpos(strtolower($parameter), 'y') !== false) { $commandline .= ' -flip'; } $successfullyProcessedFilters[] = $filterkey; } break; case 'edge': if ($this->ImageMagickSwitchAvailable('edge')) { $parameter = !empty($parameter) ? $parameter : 2; $commandline .= ' -edge ' . escapeshellarg(!empty($parameter) ? intval($parameter) : 1); $successfullyProcessedFilters[] = $filterkey; } break; case 'emb': if ($this->ImageMagickSwitchAvailable(array('emboss', 'negate'))) { $parameter = !empty($parameter) ? $parameter : 2; $commandline .= ' -emboss ' . escapeshellarg(intval($parameter)); if ($parameter < 2) { $commandline .= ' -negate'; // ImageMagick negates the image for some reason with '-emboss 1'; } $successfullyProcessedFilters[] = $filterkey; } break; case 'lvl': @(list($band, $method, $threshold) = explode('|', $parameter)); $band = $band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band)) : '*'; $method = strlen($method) > 0 ? intval($method) : 2; $threshold = strlen($threshold) > 0 ? min(max(floatval($threshold), 0), 100) : 0.1; $band = preg_replace('#[^RGBA\\*]#', '', strtoupper($band)); if ($method > 1 && !$this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) { // Because ImageMagick processing happens before PHP-GD filters, and because some // clipping is involved in the "lvl" filter, if "lvl" happens before "wb" then the // "wb" filter will have (almost) no effect. Therefore, if "wb" is enabled then // force the "lvl" filter to be processed by GD, not ImageMagick. foreach ($this->fltr as $fltr_key => $fltr_value) { list($fltr_cmd) = explode('|', $fltr_value); if ($fltr_cmd == 'wb') { $this->DebugMessage('Setting "lvl" filter method to "0" (from "' . $method . '") because white-balance filter also enabled', __FILE__, __LINE__); $method = 0; } } } switch ($method) { case 0: // internal RGB // internal RGB case 1: // internal grayscale break; case 2: // ImageMagick "contrast-stretch" if ($this->ImageMagickSwitchAvailable('contrast-stretch')) { if ($band != '*') { $commandline .= ' -channel ' . escapeshellarg(strtoupper($band)); } $threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure //$commandline .= ' -contrast-stretch '.escapeshellarg($threshold.'%'); $commandline .= ' -contrast-stretch \'' . $threshold . '%\''; if ($band != '*') { $commandline .= ' +channel'; } $successfullyProcessedFilters[] = $filterkey; } break; case 3: // ImageMagick "normalize" if ($this->ImageMagickSwitchAvailable('normalize')) { if ($band != '*') { $commandline .= ' -channel ' . escapeshellarg(strtoupper($band)); } $commandline .= ' -normalize'; if ($band != '*') { $commandline .= ' +channel'; } $successfullyProcessedFilters[] = $filterkey; } break; default: $this->DebugMessage('unsupported method (' . $method . ') for "lvl" filter', __FILE__, __LINE__); break; } if (isset($this->fltr[$filterkey]) && $method > 1) { $this->fltr[$filterkey] = $command . '|' . $band . '|0|' . $threshold; $this->DebugMessage('filter "lvl" remapped from method "' . $method . '" to method "0" because ImageMagick support is missing', __FILE__, __LINE__); } break; case 'wb': if ($this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) { @(list($threshold) = explode('|', $parameter)); $threshold = !empty($threshold) ? min(max(floatval($threshold), 0), 100) : 0.1; $threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure //$commandline .= ' -channel R -contrast-stretch '.escapeshellarg($threshold.'%'); // doesn't work on Windows because most versions of PHP do not properly //$commandline .= ' -channel G -contrast-stretch '.escapeshellarg($threshold.'%'); // escape special characters (such as %) and just replace them with spaces //$commandline .= ' -channel B -contrast-stretch '.escapeshellarg($threshold.'%'); // https://bugs.php.net/bug.php?id=43261 $commandline .= ' -channel R -contrast-stretch \'' . $threshold . '%\''; $commandline .= ' -channel G -contrast-stretch \'' . $threshold . '%\''; $commandline .= ' -channel B -contrast-stretch \'' . $threshold . '%\''; $commandline .= ' +channel'; $successfullyProcessedFilters[] = $filterkey; } break; case 'blur': if ($this->ImageMagickSwitchAvailable('blur')) { @(list($radius) = explode('|', $parameter)); $radius = !empty($radius) ? min(max(intval($radius), 0), 25) : 1; $commandline .= ' -blur ' . escapeshellarg($radius); $successfullyProcessedFilters[] = $filterkey; } break; case 'gblr': @(list($radius) = explode('|', $parameter)); $radius = !empty($radius) ? min(max(intval($radius), 0), 25) : 1; // "-gaussian" changed to "-gaussian-blur" sometime around 2009 if ($this->ImageMagickSwitchAvailable('gaussian-blur')) { $commandline .= ' -gaussian-blur ' . escapeshellarg($radius); $successfullyProcessedFilters[] = $filterkey; } elseif ($this->ImageMagickSwitchAvailable('gaussian')) { $commandline .= ' -gaussian ' . escapeshellarg($radius); $successfullyProcessedFilters[] = $filterkey; } break; case 'usm': if ($this->ImageMagickSwitchAvailable('unsharp')) { @(list($amount, $radius, $threshold) = explode('|', $parameter)); $amount = $amount ? min(max(intval($radius), 0), 255) : 80; $radius = $radius ? min(max(intval($radius), 0), 10) : 0.5; $threshold = strlen($threshold) ? min(max(intval($radius), 0), 50) : 3; $commandline .= ' -unsharp ' . escapeshellarg(number_format($radius * 2 - 1, 2, '.', '') . 'x1+' . number_format($amount / 100, 2, '.', '') . '+' . number_format($threshold / 100, 2, '.', '')); $successfullyProcessedFilters[] = $filterkey; } break; case 'bord': if ($this->ImageMagickSwitchAvailable(array('border', 'bordercolor', 'thumbnail', 'crop'))) { if (!$this->zc) { @(list($width, $rX, $rY, $color) = explode('|', $parameter)); $width = intval($width); $rX = intval($rX); $rY = intval($rY); if ($width && !$rX && !$rY) { if (!phpthumb_functions::IsHexColor($color)) { $color = !empty($this->bc) && phpthumb_functions::IsHexColor($this->bc) ? $this->bc : '000000'; } $commandline .= ' -border ' . escapeshellarg(intval($width)); $commandline .= ' -bordercolor ' . escapeshellarg('#' . $color); if (preg_match('# \\-crop "([0-9]+)x([0-9]+)\\+0\\+0" #', $commandline, $matches)) { $commandline = str_replace(' -crop "' . $matches[1] . 'x' . $matches[2] . '+0+0" ', ' -crop ' . escapeshellarg($matches[1] - 2 * $width . 'x' . ($matches[2] - 2 * $width) . '+0+0') . ' ', $commandline); } elseif (preg_match('# \\-' . $IMresizeParameter . ' "([0-9]+)x([0-9]+)" #', $commandline, $matches)) { $commandline = str_replace(' -' . $IMresizeParameter . ' "' . $matches[1] . 'x' . $matches[2] . '" ', ' -' . $IMresizeParameter . ' ' . escapeshellarg($matches[1] - 2 * $width . 'x' . ($matches[2] - 2 * $width)) . ' ', $commandline); } $successfullyProcessedFilters[] = $filterkey; } } } break; case 'crop': break; case 'sblr': break; case 'mean': break; case 'smth': break; case 'bvl': break; case 'wmi': break; case 'wmt': break; case 'over': break; case 'hist': break; case 'fram': break; case 'drop': break; case 'mask': break; case 'elip': break; case 'ric': break; case 'stc': break; case 'size': break; default: $this->DebugMessage('Unknown $this->fltr[' . $filterkey . '] (' . $filtercommand . ') -- deleting filter command', __FILE__, __LINE__); $successfullyProcessedFilters[] = $filterkey; break; } if (!isset($this->fltr[$filterkey])) { $this->DebugMessage('Processed $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); } else { $this->DebugMessage('Skipping $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); } } $this->DebugMessage('Remaining $this->fltr after ImageMagick: (' . $this->phpThumbDebugVarDump($this->fltr) . ')', __FILE__, __LINE__); if (count($this->fltr) > 0) { $this->useRawIMoutput = false; } if (preg_match('#jpe?g#i', $outputFormat) && $this->q) { if ($this->ImageMagickSwitchAvailable(array('quality', 'interlace'))) { $commandline .= ' -quality ' . escapeshellarg($this->thumbnailQuality); if ($this->config_output_interlace) { // causes weird things with animated GIF... leave for JPEG only $commandline .= ' -interlace line '; // Use Line or Plane to create an interlaced PNG or GIF or progressive JPEG image } } } $commandline .= ' ' . escapeshellarg(preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $this->sourceFilename) . ($outputFormat == 'gif' ? '' : '[' . intval($this->sfn) . ']')); // [0] means first frame of (GIF) animation, can be ignored $commandline .= ' ' . $outputFormat . ':' . escapeshellarg($IMtempfilename); if (!$this->iswindows) { $commandline .= ' 2>&1'; } $this->DebugMessage('ImageMagick called as (' . $commandline . ')', __FILE__, __LINE__); $IMresult = phpthumb_functions::SafeExec($commandline); clearstatcache(); if (!@file_exists($IMtempfilename) || !@filesize($IMtempfilename)) { $this->FatalError('ImageMagick failed with message (' . trim($IMresult) . ')'); $this->DebugMessage('ImageMagick failed with message (' . trim($IMresult) . ')', __FILE__, __LINE__); if ($this->iswindows && !$IMresult) { $this->DebugMessage('Check to make sure that PHP has read+write permissions to "' . dirname($IMtempfilename) . '"', __FILE__, __LINE__); } } else { foreach ($successfullyProcessedFilters as $dummy => $filterkey) { unset($this->fltr[$filterkey]); } $this->IMresizedData = file_get_contents($IMtempfilename); $getimagesize_imresized = @GetImageSize($IMtempfilename); $this->DebugMessage('GetImageSize(' . $IMtempfilename . ') returned [w=' . $getimagesize_imresized[0] . ';h=' . $getimagesize_imresized[1] . ';f=' . $getimagesize_imresized[2] . ']', __FILE__, __LINE__); if ($this->config_max_source_pixels > 0 && $getimagesize_imresized[0] * $getimagesize_imresized[1] > $this->config_max_source_pixels) { $this->DebugMessage('skipping ImageMagickThumbnailToGD::' . $ImageCreateFunction . '() because IM output is too large (' . $getimagesize_imresized[0] . 'x' . $getimagesize_imresized[0] . ' = ' . $getimagesize_imresized[0] * $getimagesize_imresized[1] . ' > ' . $this->config_max_source_pixels . ')', __FILE__, __LINE__); } elseif (function_exists(@$ImageCreateFunction) && ($this->gdimg_source = @$ImageCreateFunction($IMtempfilename))) { $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); $this->DebugMessage('ImageMagickThumbnailToGD::' . $ImageCreateFunction . '() succeeded, $this->gdimg_source is now (' . $this->source_width . 'x' . $this->source_height . ')', __FILE__, __LINE__); $this->DebugMessage('ImageMagickThumbnailToGD() returning $this->IMresizedData (' . strlen($this->IMresizedData) . ' bytes)', __FILE__, __LINE__); } else { $this->useRawIMoutput = true; $this->DebugMessage('$this->useRawIMoutput set to TRUE because ' . @$ImageCreateFunction . '(' . $IMtempfilename . ') failed', __FILE__, __LINE__); } return true; } if (file_exists($IMtempfilename)) { $this->DebugMessage('deleting "' . $IMtempfilename . '"', __FILE__, __LINE__); @unlink($IMtempfilename); } } elseif ($this->issafemode) { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because PHP safe_mode is enabled and phpThumb_tempnam() failed', __FILE__, __LINE__); $this->useRawIMoutput = false; } else { if (file_exists($IMtempfilename)) { $this->DebugMessage('deleting "' . $IMtempfilename . '"', __FILE__, __LINE__); @unlink($IMtempfilename); } $this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpThumb_tempnam() failed', __FILE__, __LINE__); } } else { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__); } $this->useRawIMoutput = false; return false; }
function phpThumbDebug() { if ($this->config_disable_debug) { return $this->ErrorImage('phpThumbDebug disabled'); } $FunctionsExistance = array('exif_thumbnail', 'gd_info', 'image_type_to_mime_type', 'ImageCopyResampled', 'ImageCopyResized', 'ImageCreate', 'ImageCreateFromString', 'ImageCreateTrueColor', 'ImageIsTrueColor', 'ImageRotate', 'ImageTypes', 'version_compare', 'ImageCreateFromGIF', 'ImageCreateFromJPEG', 'ImageCreateFromPNG', 'ImageCreateFromWBMP', 'ImageCreateFromXBM', 'ImageCreateFromXPM', 'ImageCreateFromString', 'ImageCreateFromGD', 'ImageCreateFromGD2', 'ImageCreateFromGD2Part', 'ImageJPEG', 'ImageGIF', 'ImagePNG', 'ImageWBMP'); $ParameterNames = array('src', 'new', 'w', 'h', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'far', 'bg', 'bc', 'file', 'goto', 'err', 'xto', 'ra', 'ar', 'aoe', 'iar', 'maxb'); $OtherVariableNames = array('phpThumbDebug', 'thumbnailQuality', 'thumbnailFormat', 'gdimg_output', 'gdimg_source', 'sourceFilename', 'source_width', 'source_height', 'thumbnailCropX', 'thumbnailCropY', 'thumbnailCropW', 'thumbnailCropH', 'exif_thumbnail_width', 'exif_thumbnail_height', 'exif_thumbnail_type', 'thumbnail_width', 'thumbnail_height', 'thumbnail_image_width', 'thumbnail_image_height'); $DebugOutput = array(); $DebugOutput[] = 'phpThumb() version = ' . $this->phpthumb_version; $DebugOutput[] = 'phpversion() = ' . @phpversion(); $DebugOutput[] = 'PHP_OS = ' . PHP_OS; $DebugOutput[] = '__FILE__ = ' . __FILE__; $DebugOutput[] = 'realpath(.) = ' . @realpath('.'); $DebugOutput[] = '$_SERVER[PHP_SELF] = ' . @$_SERVER['PHP_SELF']; $DebugOutput[] = '$_SERVER[HTTP_REFERER] = ' . @$_SERVER['HTTP_REFERER']; $DebugOutput[] = '$_SERVER[QUERY_STRING] = ' . @$_SERVER['QUERY_STRING']; $DebugOutput[] = '$_SERVER[PATH_INFO] = ' . @$_SERVER['PATH_INFO']; $DebugOutput[] = '$_SERVER[DOCUMENT_ROOT] = ' . @$_SERVER['DOCUMENT_ROOT']; $DebugOutput[] = 'getenv(DOCUMENT_ROOT) = ' . @getenv('DOCUMENT_ROOT'); $DebugOutput[] = ''; $DebugOutput[] = 'get_magic_quotes_gpc() = ' . $this->phpThumbDebugVarDump(@get_magic_quotes_gpc()); $DebugOutput[] = 'get_magic_quotes_runtime() = ' . $this->phpThumbDebugVarDump(@get_magic_quotes_runtime()); $DebugOutput[] = 'error_reporting() = ' . $this->phpThumbDebugVarDump(error_reporting()); $DebugOutput[] = 'ini_get(error_reporting) = ' . $this->phpThumbDebugVarDump(@ini_get('error_reporting')); $DebugOutput[] = 'ini_get(display_errors) = ' . $this->phpThumbDebugVarDump(@ini_get('display_errors')); $DebugOutput[] = 'ini_get(allow_url_fopen) = ' . $this->phpThumbDebugVarDump(@ini_get('allow_url_fopen')); $DebugOutput[] = 'ini_get(disable_functions) = ' . $this->phpThumbDebugVarDump(@ini_get('disable_functions')); $DebugOutput[] = 'ini_get(safe_mode) = ' . $this->phpThumbDebugVarDump(@ini_get('safe_mode')); $DebugOutput[] = 'ini_get(open_basedir) = ' . $this->phpThumbDebugVarDump(@ini_get('open_basedir')); $DebugOutput[] = 'ini_get(memory_limit) = ' . $this->phpThumbDebugVarDump(@ini_get('memory_limit')); $DebugOutput[] = 'ini_get(max_execution_time) = ' . $this->phpThumbDebugVarDump(@ini_get('max_execution_time')); $DebugOutput[] = 'get_cfg_var(memory_limit) = ' . $this->phpThumbDebugVarDump(@get_cfg_var('memory_limit')); $DebugOutput[] = 'memory_get_usage() = ' . (function_exists('memory_get_usage') ? $this->phpThumbDebugVarDump(@memory_get_usage()) : 'n/a'); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_prefer_imagemagick = ' . $this->phpThumbDebugVarDump($this->config_prefer_imagemagick); $DebugOutput[] = '$this->config_imagemagick_path = ' . $this->phpThumbDebugVarDump($this->config_imagemagick_path); $DebugOutput[] = 'SafeExec(which convert) = ' . trim(phpthumb_functions::SafeExec('which convert')); $IMpathUsed = $this->config_imagemagick_path ? $this->config_imagemagick_path : trim(phpthumb_functions::SafeExec('which convert')); $DebugOutput[] = '[actual ImageMagick path used] = ' . $this->phpThumbDebugVarDump($IMpathUsed); $DebugOutput[] = 'file_exists([actual ImageMagick path used]) = ' . $this->phpThumbDebugVarDump(file_exists($IMpathUsed)); $DebugOutput[] = 'ImageMagickVersion() = ' . $this->ImageMagickVersion(); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_cache_directory = ' . $this->phpThumbDebugVarDump($this->config_cache_directory); $DebugOutput[] = '$this->config_cache_disable_warning = ' . $this->phpThumbDebugVarDump($this->config_cache_disable_warning); $DebugOutput[] = '$this->config_cache_maxage = ' . $this->phpThumbDebugVarDump($this->config_cache_maxage); $DebugOutput[] = '$this->config_cache_maxsize = ' . $this->phpThumbDebugVarDump($this->config_cache_maxsize); $DebugOutput[] = '$this->config_cache_maxfiles = ' . $this->phpThumbDebugVarDump($this->config_cache_maxfiles); $DebugOutput[] = '$this->cache_filename = ' . $this->phpThumbDebugVarDump($this->cache_filename); $DebugOutput[] = 'is_readable($this->config_cache_directory) = ' . $this->phpThumbDebugVarDump(is_readable($this->config_cache_directory)); $DebugOutput[] = 'is_writable($this->config_cache_directory) = ' . $this->phpThumbDebugVarDump(is_writable($this->config_cache_directory)); $DebugOutput[] = 'is_readable($this->cache_filename) = ' . $this->phpThumbDebugVarDump(is_readable($this->cache_filename)); $DebugOutput[] = 'is_writable($this->cache_filename) = ' . (file_exists($this->cache_filename) ? $this->phpThumbDebugVarDump(is_writable($this->cache_filename)) : 'n/a'); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_document_root = ' . $this->phpThumbDebugVarDump($this->config_document_root); $DebugOutput[] = '$this->config_temp_directory = ' . $this->phpThumbDebugVarDump($this->config_temp_directory); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_output_format = ' . $this->phpThumbDebugVarDump($this->config_output_format); $DebugOutput[] = '$this->config_output_maxwidth = ' . $this->phpThumbDebugVarDump($this->config_output_maxwidth); $DebugOutput[] = '$this->config_output_maxheight = ' . $this->phpThumbDebugVarDump($this->config_output_maxheight); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_error_message_image_default = ' . $this->phpThumbDebugVarDump($this->config_error_message_image_default); $DebugOutput[] = '$this->config_error_bgcolor = ' . $this->phpThumbDebugVarDump($this->config_error_bgcolor); $DebugOutput[] = '$this->config_error_textcolor = ' . $this->phpThumbDebugVarDump($this->config_error_textcolor); $DebugOutput[] = '$this->config_error_fontsize = ' . $this->phpThumbDebugVarDump($this->config_error_fontsize); $DebugOutput[] = '$this->config_error_die_on_error = ' . $this->phpThumbDebugVarDump($this->config_error_die_on_error); $DebugOutput[] = '$this->config_error_silent_die_on_error = ' . $this->phpThumbDebugVarDump($this->config_error_silent_die_on_error); $DebugOutput[] = '$this->config_error_die_on_source_failure = ' . $this->phpThumbDebugVarDump($this->config_error_die_on_source_failure); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_nohotlink_enabled = ' . $this->phpThumbDebugVarDump($this->config_nohotlink_enabled); $DebugOutput[] = '$this->config_nohotlink_valid_domains = ' . $this->phpThumbDebugVarDump($this->config_nohotlink_valid_domains); $DebugOutput[] = '$this->config_nohotlink_erase_image = ' . $this->phpThumbDebugVarDump($this->config_nohotlink_erase_image); $DebugOutput[] = '$this->config_nohotlink_text_message = ' . $this->phpThumbDebugVarDump($this->config_nohotlink_text_message); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_nooffsitelink_enabled = ' . $this->phpThumbDebugVarDump($this->config_nooffsitelink_enabled); $DebugOutput[] = '$this->config_nooffsitelink_valid_domains = ' . $this->phpThumbDebugVarDump($this->config_nooffsitelink_valid_domains); $DebugOutput[] = '$this->config_nooffsitelink_require_refer = ' . $this->phpThumbDebugVarDump($this->config_nooffsitelink_require_refer); $DebugOutput[] = '$this->config_nooffsitelink_erase_image = ' . $this->phpThumbDebugVarDump($this->config_nooffsitelink_erase_image); $DebugOutput[] = '$this->config_nooffsitelink_text_message = ' . $this->phpThumbDebugVarDump($this->config_nooffsitelink_text_message); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_high_security_enabled = ' . $this->phpThumbDebugVarDump($this->config_high_security_enabled); $DebugOutput[] = '$this->config_allow_src_above_docroot = ' . $this->phpThumbDebugVarDump($this->config_allow_src_above_docroot); $DebugOutput[] = '$this->config_allow_src_above_phpthumb = ' . $this->phpThumbDebugVarDump($this->config_allow_src_above_phpthumb); $DebugOutput[] = '$this->config_allow_parameter_file = ' . $this->phpThumbDebugVarDump($this->config_allow_parameter_file); $DebugOutput[] = '$this->config_allow_parameter_goto = ' . $this->phpThumbDebugVarDump($this->config_allow_parameter_goto); $DebugOutput[] = ''; $DebugOutput[] = '$this->config_max_source_pixels = ' . $this->phpThumbDebugVarDump($this->config_max_source_pixels); $DebugOutput[] = '$this->config_use_exif_thumbnail_for_speed = ' . $this->phpThumbDebugVarDump($this->config_use_exif_thumbnail_for_speed); $DebugOutput[] = '$this->config_border_hexcolor = ' . $this->phpThumbDebugVarDump($this->config_border_hexcolor); $DebugOutput[] = '$this->config_background_hexcolor = ' . $this->phpThumbDebugVarDump($this->config_background_hexcolor); $DebugOutput[] = '$this->config_ttf_directory = ' . $this->phpThumbDebugVarDump($this->config_ttf_directory); $DebugOutput[] = ''; foreach ($OtherVariableNames as $varname) { $value = $this->{$varname}; $DebugOutput[] = '$this->' . str_pad($varname, 27, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); } $DebugOutput[] = 'strlen($this->rawImageData) = ' . strlen(@$this->rawImageData); $DebugOutput[] = 'strlen($this->exif_thumbnail_data) = ' . strlen(@$this->exif_thumbnail_data); $DebugOutput[] = ''; foreach ($ParameterNames as $varname) { $value = $this->{$varname}; $DebugOutput[] = '$this->' . str_pad($varname, 4, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); } $DebugOutput[] = ''; foreach ($FunctionsExistance as $functionname) { $DebugOutput[] = 'builtin_function_exists(' . $functionname . ')' . str_repeat(' ', 23 - strlen($functionname)) . ' = ' . $this->phpThumbDebugVarDump(phpthumb_functions::builtin_function_exists($functionname)); } $DebugOutput[] = ''; $gd_info = phpthumb_functions::gd_info(); foreach ($gd_info as $key => $value) { $DebugOutput[] = 'gd_info.' . str_pad($key, 34, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); } $DebugOutput[] = ''; $exif_info = phpthumb_functions::exif_info(); foreach ($exif_info as $key => $value) { $DebugOutput[] = 'exif_info.' . str_pad($key, 26, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); } $DebugOutput[] = ''; if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) { foreach ($ApacheLookupURIarray as $key => $value) { $DebugOutput[] = 'ApacheLookupURIarray.' . str_pad($key, 15, ' ', STR_PAD_RIGHT) . ' = ' . $this->phpThumbDebugVarDump($value); } } else { $DebugOutput[] = 'ApacheLookupURIarray() -- FAILED'; } $DebugOutput[] = ''; if (isset($_GET) && is_array($_GET)) { foreach ($_GET as $key => $value) { $DebugOutput[] = '$_GET[' . $key . ']' . str_repeat(' ', 30 - strlen($key)) . '= ' . $this->phpThumbDebugVarDump($value); } } if (isset($_POST) && is_array($_POST)) { foreach ($_POST as $key => $value) { $DebugOutput[] = '$_POST[' . $key . ']' . str_repeat(' ', 29 - strlen($key)) . '= ' . $this->phpThumbDebugVarDump($value); } } $DebugOutput[] = ''; $DebugOutput[] = '$this->debugmessages:'; foreach ($this->debugmessages as $errorstring) { $DebugOutput[] = ' * ' . $errorstring; } $DebugOutput[] = ''; $DebugOutput[] = '$this->debugtiming:'; foreach ($this->debugtiming as $timestamp => $timingstring) { $DebugOutput[] = ' * ' . $timestamp . ' ' . $timingstring; } $DebugOutput[] = ' * Total processing time: ' . number_format(max(array_keys($this->debugtiming)) - min(array_keys($this->debugtiming)), 6); return $this->ErrorImage(implode("\n", $DebugOutput), 700, 500); }
function ImageMagickThumbnailToGD() { // http://www.imagemagick.org/script/command-line-options.php if (ini_get('safe_mode')) { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__); $this->useRawIMoutput = false; return false; } $this->useRawIMoutput = true; if (phpthumb_functions::gd_version()) { // if GD is not available, must use whatever ImageMagick can output // $UnAllowedParameters contains options that can only be processed in GD, not ImageMagick // note: 'fltr' *may* need to be processed by GD, but we'll check that in more detail below $UnAllowedParameters = array('xto', 'ar', 'bg', 'bc'); // 'ra' may be part of this list, if not a multiple of 90° foreach ($UnAllowedParameters as $parameter) { if (isset($this->{$parameter})) { $this->DebugMessage('$this->useRawIMoutput=false because "' . $parameter . '" is set', __FILE__, __LINE__); $this->useRawIMoutput = false; break; } } } $this->DebugMessage('$this->useRawIMoutput=' . ($this->useRawIMoutput ? 'true' : 'false') . ' after checking $UnAllowedParameters', __FILE__, __LINE__); $outputFormat = $this->thumbnailFormat; if (phpthumb_functions::gd_version()) { if ($this->useRawIMoutput) { switch ($this->thumbnailFormat) { case 'gif': $ImageCreateFunction = 'ImageCreateFromGIF'; $this->is_alpha = true; break; case 'png': $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; break; case 'jpg': case 'jpeg': $ImageCreateFunction = 'ImageCreateFromJPEG'; break; default: $this->DebugMessage('Forcing output to PNG because $this->thumbnailFormat (' . $this->thumbnailFormat . ' is not a GD-supported format)', __FILE__, __LINE__); $outputFormat = 'png'; $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; $this->useRawIMoutput = false; break; } if (!function_exists(@$ImageCreateFunction)) { // ImageMagickThumbnailToGD() depends on ImageCreateFromPNG/ImageCreateFromGIF //$this->DebugMessage('ImageMagickThumbnailToGD() aborting because '.@$ImageCreateFunction.'() is not available', __FILE__, __LINE__); $this->useRawIMoutput = true; //return false; } } else { $outputFormat = 'png'; $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; $this->useRawIMoutput = false; } } if (!$this->sourceFilename && $this->rawImageData) { if ($IMtempSourceFilename = $this->phpThumb_tempnam()) { $IMtempSourceFilename = realpath($IMtempSourceFilename); $this->sourceFilename = $IMtempSourceFilename; $this->DebugMessage('ImageMagickThumbnailToGD() setting $this->sourceFilename to "' . $IMtempSourceFilename . '" from $this->rawImageData (' . strlen($this->rawImageData) . ' bytes)', __FILE__, __LINE__); } } if (!$this->sourceFilename) { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty', __FILE__, __LINE__); $this->useRawIMoutput = false; return false; } $commandline = $this->ImageMagickCommandlineBase(); if ($commandline) { if ($IMtempfilename = $this->phpThumb_tempnam()) { $IMtempfilename = realpath($IMtempfilename); $IMuseExplicitImageOutputDimensions = false; if ($this->ImageMagickSwitchAvailable('thumbnail') && $this->config_imagemagick_use_thumbnail) { $IMresizeParameter = 'thumbnail'; } else { $IMresizeParameter = 'resize'; // some (older? around 2002) versions of IM won't accept "-resize 100x" but require "-resize 100x100" $commandline_test = $this->ImageMagickCommandlineBase() . ' logo: -resize 1x "' . $IMtempfilename . '" 2>&1'; $IMresult_test = phpthumb_functions::SafeExec($commandline_test); $IMuseExplicitImageOutputDimensions = preg_match('/image dimensions are zero/i', $IMresult_test); $this->DebugMessage('IMuseExplicitImageOutputDimensions = ' . intval($IMuseExplicitImageOutputDimensions), __FILE__, __LINE__); if ($fp_im_temp = @fopen($IMtempfilename, 'wb')) { // erase temp image so ImageMagick logo doesn't get output if other processing fails fclose($fp_im_temp); } } if (!is_null($this->dpi) && $this->ImageMagickSwitchAvailable('density')) { // for raster source formats only (WMF, PDF, etc) $commandline .= ' -density ' . $this->dpi; } ob_start(); $getimagesize = GetImageSize($this->sourceFilename); $GetImageSizeError = ob_get_contents(); ob_end_clean(); if (is_array($getimagesize)) { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') SUCCEEDED: ' . serialize($getimagesize), __FILE__, __LINE__); } else { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') FAILED with error "' . $GetImageSizeError . '"', __FILE__, __LINE__); } if (is_array($getimagesize)) { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') returned [w=' . $getimagesize[0] . ';h=' . $getimagesize[1] . ';f=' . $getimagesize[2] . ']', __FILE__, __LINE__); $this->source_width = $getimagesize[0]; $this->source_height = $getimagesize[1]; $this->DebugMessage('source dimensions set to ' . $this->source_width . 'x' . $this->source_height, __FILE__, __LINE__); $this->SetOrientationDependantWidthHeight(); if (!preg_match('/(' . implode('|', $this->AlphaCapableFormats) . ')/i', $outputFormat)) { // not a transparency-capable format $commandline .= ' -background "#' . ($this->bg ? $this->bg : 'FFFFFF') . '"'; if ($getimagesize[2] == 1) { // GIF $commandline .= ' -flatten'; } } if ($getimagesize[2] == 1) { // GIF $commandline .= ' -coalesce'; // may be needed for animated GIFs } if ($this->source_width || $this->source_height) { if ($this->zc) { $borderThickness = 0; if (!empty($this->fltr)) { foreach ($this->fltr as $key => $value) { if (preg_match('/^bord\\|([0-9]+)/', $value, $matches)) { $borderThickness = $matches[1]; break; } } } $wAll = intval(max($this->w, $this->wp, $this->wl, $this->ws)) - 2 * $borderThickness; $hAll = intval(max($this->h, $this->hp, $this->hl, $this->hs)) - 2 * $borderThickness; $imAR = $this->source_width / $this->source_height; $zcAR = $wAll && $hAll ? $wAll / $hAll : 1; $side = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll)); $sideX = phpthumb_functions::nonempty_min($this->source_width, $wAll, round($hAll * $zcAR)); $sideY = phpthumb_functions::nonempty_min($this->source_height, $hAll, round($wAll / $zcAR)); $thumbnailH = round(max($sideY, $sideY * $zcAR / $imAR)); if ($IMuseExplicitImageOutputDimensions) { $commandline .= ' -' . $IMresizeParameter . ' ' . $thumbnailH . 'x' . $thumbnailH; } else { $commandline .= ' -' . $IMresizeParameter . ' x' . $thumbnailH; } switch (strtoupper($this->zc)) { case 'T': $commandline .= ' -gravity north'; break; case 'B': $commandline .= ' -gravity south'; break; case 'L': $commandline .= ' -gravity west'; break; case 'R': $commandline .= ' -gravity east'; break; case 'TL': $commandline .= ' -gravity northwest'; break; case 'TR': $commandline .= ' -gravity northeast'; break; case 'BL': $commandline .= ' -gravity southwest'; break; case 'BR': $commandline .= ' -gravity southeast'; break; case '1': case 'C': default: $commandline .= ' -gravity center'; break; } if ($wAll > 0 && $hAll > 0) { $commandline .= ' -crop ' . $wAll . 'x' . $hAll . '+0+0'; } else { $commandline .= ' -crop ' . $side . 'x' . $side . '+0+0'; } if ($this->ImageMagickSwitchAvailable('repage')) { $commandline .= ' +repage'; } else { $this->DebugMessage('Skipping "+repage" because ImageMagick (v' . $this->ImageMagickVersion() . ') does not support it', __FILE__, __LINE__); } } elseif ($this->sw || $this->sh || $this->sx || $this->sy) { $commandline .= ' -crop ' . ($this->sw ? $this->sw : $this->source_width) . 'x' . ($this->sh ? $this->sh : $this->source_height) . '+' . $this->sx . '+' . $this->sy; // this is broken for aoe=1, but unsure how to fix. Send advice to info@silisoftware.com if ($this->w || $this->h) { if ($this->ImageMagickSwitchAvailable('repage')) { $commandline .= ' -repage'; } else { $this->DebugMessage('Skipping "-repage" because ImageMagick (v' . $this->ImageMagickVersion() . ') does not support it', __FILE__, __LINE__); } if ($IMuseExplicitImageOutputDimensions) { if ($this->w && !$this->h) { $this->h = ceil($this->w / ($this->source_width / $this->source_height)); } elseif ($this->h && !$this->w) { $this->w = ceil($this->h * ($this->source_width / $this->source_height)); } } $commandline .= ' -' . $IMresizeParameter . ' ' . $this->w . 'x' . $this->h; } } else { if ($this->iar && intval($this->w) > 0 && intval($this->h) > 0) { //$commandline .= ' -'.$IMresizeParameter.' '.$this->w.'x'.$this->h.'!'; list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra); $nw = round($nw) != 0 ? round($nw) : ''; $nh = round($nh) != 0 ? round($nh) : ''; $commandline .= ' -' . $IMresizeParameter . ' ' . $nw . 'x' . $nh . '!'; } else { $this->w = ($this->aoe || $this->far) && $this->w ? $this->w : ($this->w ? phpthumb_functions::nonempty_min($this->w, $getimagesize[0]) : ''); $this->h = ($this->aoe || $this->far) && $this->h ? $this->h : ($this->h ? phpthumb_functions::nonempty_min($this->h, $getimagesize[1]) : ''); if ($this->w || $this->h) { if ($IMuseExplicitImageOutputDimensions) { if ($this->w && !$this->h) { $this->h = ceil($this->w / ($this->source_width / $this->source_height)); } elseif ($this->h && !$this->w) { $this->w = ceil($this->h * ($this->source_width / $this->source_height)); } } //$commandline .= ' -'.$IMresizeParameter.' '.$this->w.'x'.$this->h; list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra); $nw = round($nw) != 0 ? round($nw) : ''; $nh = round($nh) != 0 ? round($nh) : ''; $commandline .= ' -' . $IMresizeParameter . ' ' . $nw . 'x' . $nh; } } } } } else { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') failed', __FILE__, __LINE__); if ($this->w || $this->h) { if ($IMuseExplicitImageOutputDimensions) { // unknown source aspect ration, just put large number and hope IM figures it out $commandline .= ' -' . $IMresizeParameter . ' ' . ($this->w ? $this->w : '9999') . 'x' . ($this->h ? $this->h : '9999'); } else { $commandline .= ' -' . $IMresizeParameter . ' ' . $this->w . 'x' . $this->h; } if ($this->iar && intval($this->w) > 0 && intval($this->h) > 0) { $commandline .= '!'; } } } if ($this->ra) { $this->ra = intval($this->ra); if ($this->ImageMagickSwitchAvailable('rotate')) { if (!preg_match('/(' . implode('|', $this->AlphaCapableFormats) . ')/i', $outputFormat) || phpthumb_functions::version_compare_replacement($this->ImageMagickVersion(), '6.3.7', '>=')) { $this->DebugMessage('Using ImageMagick rotate', __FILE__, __LINE__); $commandline .= ' -rotate ' . $this->ra; if ($this->ra % 90 != 0) { if (preg_match('/(' . implode('|', $this->AlphaCapableFormats) . ')/i', $outputFormat)) { // alpha-capable format $commandline .= ' -background rgba(255,255,255,0)'; } else { $commandline .= ' -background "#' . ($this->bg ? $this->bg : 'FFFFFF') . '"'; } } $this->ra = 0; } else { $this->DebugMessage('Not using ImageMagick rotate because alpha background buggy before v6.3.7', __FILE__, __LINE__); } } else { $this->DebugMessage('Not using ImageMagick rotate because not supported', __FILE__, __LINE__); } } foreach ($this->fltr as $filterkey => $filtercommand) { @(list($command, $parameter) = explode('|', $filtercommand, 2)); switch ($command) { case 'brit': if ($this->ImageMagickSwitchAvailable('modulate')) { $commandline .= ' -modulate ' . (100 + $parameter) . ',100,100'; unset($this->fltr[$filterkey]); } break; case 'cont': if ($this->ImageMagickSwitchAvailable('contrast')) { $contDiv10 = round($parameter / 10); if ($contDiv10 > 0) { for ($i = 0; $i < $contDiv10; $i++) { $commandline .= ' -contrast'; // increase contrast by 10% } } elseif ($contDiv10 < 0) { for ($i = $contDiv10; $i < 0; $i++) { $commandline .= ' +contrast'; // decrease contrast by 10% } } else { // do nothing } unset($this->fltr[$filterkey]); } break; case 'ds': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { if ($parameter == 100) { $commandline .= ' -colorspace GRAY -modulate 100,0,100'; } else { $commandline .= ' -modulate 100,' . (100 - $parameter) . ',100'; } unset($this->fltr[$filterkey]); } break; case 'sat': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { if ($parameter == -100) { $commandline .= ' -colorspace GRAY -modulate 100,0,100'; } else { $commandline .= ' -modulate 100,' . (100 + $parameter) . ',100'; } unset($this->fltr[$filterkey]); } break; case 'gray': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { $commandline .= ' -colorspace GRAY -modulate 100,0,100'; //$commandline .= ' -colorspace GRAY'; unset($this->fltr[$filterkey]); } break; case 'clr': if ($this->ImageMagickSwitchAvailable(array('fill', 'colorize'))) { @(list($amount, $color) = explode('|', $parameter)); $commandline .= ' -fill "#' . $color . '" -colorize ' . $amount; } break; case 'sep': if ($this->ImageMagickSwitchAvailable('sepia-tone')) { @(list($amount, $color) = explode('|', $parameter)); $amount = $amount ? $amount : 80; if (!$color) { $commandline .= ' -sepia-tone ' . $amount . '%'; unset($this->fltr[$filterkey]); } } break; case 'gam': if ($this->ImageMagickSwitchAvailable('gamma')) { $commandline .= ' -gamma ' . $parameter; unset($this->fltr[$filterkey]); } break; case 'neg': if ($this->ImageMagickSwitchAvailable('negate')) { $commandline .= ' -negate'; unset($this->fltr[$filterkey]); } break; case 'th': if ($this->ImageMagickSwitchAvailable(array('threshold', 'dither', 'monochrome'))) { $commandline .= ' -threshold ' . round($parameter / 2.55) . '% -dither -monochrome'; unset($this->fltr[$filterkey]); } break; case 'rcd': if ($this->ImageMagickSwitchAvailable(array('colors', 'dither'))) { @(list($colors, $dither) = explode('|', $parameter)); $colors = $colors ? (int) $colors : 256; $dither = strlen($dither) > 0 ? (bool) $dither : true; $commandline .= ' -colors ' . max($colors, 8); // ImageMagick will otherwise fail with "cannot quantize to fewer than 8 colors" $commandline .= $dither ? ' -dither' : ' +dither'; unset($this->fltr[$filterkey]); } break; case 'flip': if ($this->ImageMagickSwitchAvailable(array('flip', 'flop'))) { if (strpos(strtolower($parameter), 'x') !== false) { $commandline .= ' -flop'; } if (strpos(strtolower($parameter), 'y') !== false) { $commandline .= ' -flip'; } unset($this->fltr[$filterkey]); } break; case 'edge': if ($this->ImageMagickSwitchAvailable('edge')) { $parameter = $parameter ? $parameter : 2; $commandline .= ' -edge ' . ($parameter ? $parameter : 1); unset($this->fltr[$filterkey]); } break; case 'emb': if ($this->ImageMagickSwitchAvailable(array('emboss', 'negate'))) { $parameter = $parameter ? $parameter : 2; $commandline .= ' -emboss ' . $parameter; if ($parameter < 2) { $commandline .= ' -negate'; // ImageMagick negates the image for some reason with '-emboss 1'; } unset($this->fltr[$filterkey]); } break; case 'lvl': @(list($band, $method, $threshold) = explode('|', $parameter)); $band = $band ? preg_replace('/[^RGBA\\*]/', '', strtoupper($band)) : '*'; $method = strlen($method) > 0 ? intval($method) : 2; $threshold = strlen($threshold) > 0 ? floatval($threshold) : 0.1; $band = preg_replace('/[^RGBA\\*]/', '', strtoupper($band)); if ($method > 1 && !$this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) { // Because ImageMagick processing happens before PHP-GD filters, and because some // clipping is involved in the "lvl" filter, if "lvl" happens before "wb" then the // "wb" filter will have (almost) no effect. Therefore, if "wb" is enabled then // force the "lvl" filter to be processed by GD, not ImageMagick. foreach ($this->fltr as $fltr_key => $fltr_value) { list($fltr_cmd) = explode('|', $fltr_value); if ($fltr_cmd == 'wb') { $this->DebugMessage('Setting "lvl" filter method to "0" (from "' . $method . '") because white-balance filter also enabled', __FILE__, __LINE__); $method = 0; } } } switch ($method) { case 0: // internal RGB // internal RGB case 1: // internal grayscale break; case 2: // ImageMagick "contrast-stretch" if ($this->ImageMagickSwitchAvailable('contrast-stretch')) { $thiscommand = ' -contrast-stretch ' . $threshold . '%'; $commandline .= $band == '*' ? $thiscommand : ' -channel ' . strtoupper($band) . $thiscommand . ' +channel'; unset($this->fltr[$filterkey]); } break; case 3: // ImageMagick "normalize" if ($this->ImageMagickSwitchAvailable('normalize')) { $thiscommand = ' -normalize'; $commandline .= $band == '*' ? $thiscommand : ' -channel ' . strtoupper($band) . $thiscommand . ' +channel'; unset($this->fltr[$filterkey]); } break; default: $this->DebugMessage('unsupported method (' . $method . ') for "lvl" filter', __FILE__, __LINE__); break; } if (isset($this->fltr[$filterkey]) && $method > 1) { $this->fltr[$filterkey] = $command . '|' . $band . '|0|' . $threshold; $this->DebugMessage('filter "lvl" remapped from method "' . $method . '" to method "0" because ImageMagick support is missing', __FILE__, __LINE__); } break; case 'wb': if ($this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) { @(list($threshold) = explode('|', $parameter)); $threshold = is_float($threshold) ? $threshold : 0.1; $commandline .= ' -channel R -contrast-stretch ' . $threshold . '%'; $commandline .= ' -channel G -contrast-stretch ' . $threshold . '%'; $commandline .= ' -channel B -contrast-stretch ' . $threshold . '%'; $commandline .= ' +channel'; unset($this->fltr[$filterkey]); } break; case 'blur': if ($this->ImageMagickSwitchAvailable('blur')) { @(list($radius) = explode('|', $parameter)); $radius = $radius ? $radius : 1; $commandline .= ' -blur ' . $radius; unset($this->fltr[$filterkey]); } break; case 'gblr': if ($this->ImageMagickSwitchAvailable('gaussian')) { @(list($radius) = explode('|', $parameter)); $radius = $radius ? $radius : 1; $commandline .= ' -gaussian ' . $radius; unset($this->fltr[$filterkey]); } break; case 'usm': if ($this->ImageMagickSwitchAvailable('unsharp')) { @(list($amount, $radius, $threshold) = explode('|', $parameter)); $amount = $amount ? $amount : 80; $radius = $radius ? $radius : 0.5; $threshold = strlen($threshold) ? $threshold : 3; $commandline .= ' -unsharp ' . number_format($radius * 2 - 1, 2) . 'x1+' . number_format($amount / 100, 2) . '+' . number_format($threshold / 100, 2); unset($this->fltr[$filterkey]); } break; case 'bord': if ($this->ImageMagickSwitchAvailable(array('border', 'bordercolor', 'thumbnail', 'crop'))) { if (!$this->zc) { @(list($width, $rX, $rY, $color) = explode('|', $parameter)); if ($width && !$rX && !$rY) { if (!phpthumb_functions::IsHexColor($color)) { $color = $this->bc ? $this->bc : '000000'; } $commandline .= ' -border ' . $width . ' -bordercolor "#' . $color . '"'; if (preg_match('# \\-crop ([0-9]+)x([0-9]+)\\+0\\+0 #', $commandline, $matches)) { $commandline = str_replace(' -crop ' . $matches[1] . 'x' . $matches[2] . '+0+0 ', ' -crop ' . ($matches[1] - 2 * $width) . 'x' . ($matches[2] - 2 * $width) . '+0+0 ', $commandline); } elseif (preg_match('# \\-' . $IMresizeParameter . ' ([0-9]+)x([0-9]+) #', $commandline, $matches)) { $commandline = str_replace(' -' . $IMresizeParameter . ' ' . $matches[1] . 'x' . $matches[2] . ' ', ' -' . $IMresizeParameter . ' ' . ($matches[1] - 2 * $width) . 'x' . ($matches[2] - 2 * $width) . ' ', $commandline); } unset($this->fltr[$filterkey]); } } } break; case 'crop': break; case 'sblr': break; case 'mean': break; case 'smth': break; case 'bvl': break; case 'wmi': break; case 'wmt': break; case 'over': break; case 'hist': break; case 'fram': break; case 'drop': break; case 'mask': break; case 'elip': break; case 'ric': break; case 'stc': break; case 'size': break; default: $this->DebugMessage('Unknown $this->fltr[' . $filterkey . '] (' . $filtercommand . ') -- deleting filter command', __FILE__, __LINE__); unset($this->fltr[$filterkey]); break; } if (!isset($this->fltr[$filterkey])) { $this->DebugMessage('Processed $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); } else { $this->DebugMessage('Skipping $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); } } $this->DebugMessage('Remaining $this->fltr after ImageMagick: (' . $this->phpThumbDebugVarDump($this->fltr) . ')', __FILE__, __LINE__); if (count($this->fltr) > 0) { $this->useRawIMoutput = false; } if (preg_match('/jpe?g/i', $outputFormat) && $this->q) { if ($this->ImageMagickSwitchAvailable(array('quality', 'interlace'))) { $commandline .= ' -quality ' . $this->thumbnailQuality; if ($this->config_output_interlace) { // causes weird things with animated GIF... leave for JPEG only $commandline .= ' -interlace line '; // Use Line or Plane to create an interlaced PNG or GIF or progressive JPEG image } } } $commandline .= ' "' . str_replace('/', DIRECTORY_SEPARATOR, $this->sourceFilename) . ($outputFormat == 'gif' ? '' : '[' . intval($this->sfn) . ']') . '"'; // [0] means first frame of (GIF) animation, can be ignored $commandline .= ' ' . $outputFormat . ':"' . $IMtempfilename . '"'; if (!$this->iswindows) { $commandline .= ' 2>&1'; } $this->DebugMessage('ImageMagick called as (' . $commandline . ')', __FILE__, __LINE__); $IMresult = phpthumb_functions::SafeExec($commandline); clearstatcache(); if (@$IMtempSourceFilename && file_exists($IMtempSourceFilename)) { @unlink($IMtempSourceFilename); } if (!@file_exists($IMtempfilename) || !@filesize($IMtempfilename)) { $this->FatalError('ImageMagick failed with message (' . trim($IMresult) . ')'); $this->DebugMessage('ImageMagick failed with message (' . trim($IMresult) . ')', __FILE__, __LINE__); if ($this->iswindows && !$IMresult) { $this->DebugMessage('Check to make sure that PHP has read+write permissions to "' . dirname($IMtempfilename) . '"', __FILE__, __LINE__); } } else { $this->IMresizedData = file_get_contents($IMtempfilename); $getimagesize_imresized = @GetImageSize($IMtempfilename); $this->DebugMessage('GetImageSize(' . $IMtempfilename . ') returned [w=' . $getimagesize_imresized[0] . ';h=' . $getimagesize_imresized[1] . ';f=' . $getimagesize_imresized[2] . ']', __FILE__, __LINE__); if ($this->config_max_source_pixels > 0 && $getimagesize_imresized[0] * $getimagesize_imresized[1] > $this->config_max_source_pixels) { $this->DebugMessage('skipping ImageMagickThumbnailToGD::' . $ImageCreateFunction . '() because IM output is too large (' . $getimagesize_imresized[0] . 'x' . $getimagesize_imresized[0] . ' = ' . $getimagesize_imresized[0] * $getimagesize_imresized[1] . ' > ' . $this->config_max_source_pixels . ')', __FILE__, __LINE__); } elseif (function_exists(@$ImageCreateFunction) && ($this->gdimg_source = @$ImageCreateFunction($IMtempfilename))) { $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); $this->DebugMessage('ImageMagickThumbnailToGD::' . $ImageCreateFunction . '() succeeded, $this->gdimg_source is now (' . $this->source_width . 'x' . $this->source_height . ')', __FILE__, __LINE__); $this->DebugMessage('ImageMagickThumbnailToGD() returning $this->IMresizedData (' . strlen($this->IMresizedData) . ' bytes)', __FILE__, __LINE__); } else { $this->useRawIMoutput = true; $this->DebugMessage('$this->useRawIMoutput set to TRUE because ' . @$ImageCreateFunction . '(' . $IMtempfilename . ') failed', __FILE__, __LINE__); } @unlink($IMtempfilename); return true; } unlink($IMtempfilename); } else { $this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpThumb_tempnam() failed', __FILE__, __LINE__); } } else { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__); } $this->useRawIMoutput = false; return false; }
function ImageMagickThumbnailToGD() { // http://www.imagemagick.org/script/command-line-options.php $this->useRawIMoutput = true; if (phpthumb_functions::gd_version()) { //$UnAllowedParameters = array('sx', 'sy', 'sw', 'sh', 'xto', 'ra', 'ar', 'bg', 'bc', 'fltr'); $UnAllowedParameters = array('xto', 'ra', 'ar', 'bg', 'bc', 'fltr'); foreach ($UnAllowedParameters as $dummy => $parameter) { if ($this->{$parameter}) { $this->DebugMessage('$this->useRawIMoutput=false because "' . $parameter . '" is set', __FILE__, __LINE__); $this->useRawIMoutput = false; break; } } } $outputFormat = $this->thumbnailFormat; if (phpthumb_functions::gd_version()) { if ($this->useRawIMoutput) { switch ($this->thumbnailFormat) { case 'gif': $ImageCreateFunction = 'ImageCreateFromGIF'; $this->is_alpha = true; break; case 'png': $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; break; case 'jpg': case 'jpeg': $ImageCreateFunction = 'ImageCreateFromJPEG'; break; default: $outputFormat = 'png'; $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; $this->useRawIMoutput = false; break; } if (!function_exists(@$ImageCreateFunction)) { // ImageMagickThumbnailToGD() depends on ImageCreateFromPNG/ImageCreateFromGIF //$this->DebugMessage('ImageMagickThumbnailToGD() aborting because '.@$ImageCreateFunction.'() is not available', __FILE__, __LINE__); $this->useRawIMoutput = true; //return false; } } else { $outputFormat = 'png'; $ImageCreateFunction = 'ImageCreateFromPNG'; $this->is_alpha = true; $this->useRawIMoutput = false; } } // http://freealter.org/doc_distrib/ImageMagick-5.1.1/www/convert.html if (!$this->sourceFilename) { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty', __FILE__, __LINE__); $this->useRawIMoutput = false; return false; } if (ini_get('safe_mode')) { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__); $this->useRawIMoutput = false; return false; } $commandline = $this->ImageMagickCommandlineBase(); if ($commandline) { if ($IMtempfilename = $this->phpThumb_tempnam()) { if (!eregi('(' . implode('|', $this->AlphaCapableFormats) . ')', $outputFormat)) { // not a transparency-capable format $commandline .= ' -background "#' . ($this->bg ? $this->bg : 'FFFFFF') . '"'; $commandline .= ' -flatten'; } $IMtempfilename = realpath($IMtempfilename); if ($getimagesize = @GetImageSize($this->sourceFilename)) { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') returned [w=' . $getimagesize[0] . ';h=' . $getimagesize[1] . ';f=' . $getimagesize[2] . ']', __FILE__, __LINE__); $this->source_width = $getimagesize[0]; $this->source_height = $getimagesize[1]; $this->DebugMessage('source dimensions set to ' . $this->source_width . 'x' . $this->source_height, __FILE__, __LINE__); $this->SetOrientationDependantWidthHeight(); $commandline .= ' -coalesce'; // may be needed for animated GIFs if ($this->source_width || $this->source_height) { if ($this->zc) { $borderThickness = 0; if (!empty($this->fltr)) { foreach ($this->fltr as $key => $value) { if (ereg('^bord\\|([0-9]+)', $value, $matches)) { $borderThickness = $matches[1]; break; } } } $wAll = intval(max($this->w, $this->wp, $this->wl, $this->ws)) - 2 * $borderThickness; $hAll = intval(max($this->h, $this->hp, $this->hl, $this->hs)) - 2 * $borderThickness; $imAR = $this->source_width / $this->source_height; //$zcAR = (($wAll && $hAll) ? $wAll / $hAll : $imAR); $zcAR = $wAll && $hAll ? $wAll / $hAll : 1; //echo '<pre>'; //var_dump($wAll); //var_dump($hAll); //var_dump($zcAR); //if (($wAll > $borderThickness) && ($wAll > $borderThickness)) { // $zcAR = ($wAll - (2 * $borderThickness)) / ($hAll - (2 * $borderThickness)); //} //echo ($wAll - (2 * $borderThickness))."\n"; //echo ($hAll - (2 * $borderThickness))."\n"; //var_dump($zcAR); $side = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll)); $sideX = phpthumb_functions::nonempty_min($this->source_width, $wAll, round($hAll * $zcAR)); $sideY = phpthumb_functions::nonempty_min($this->source_height, $hAll, round($wAll / $zcAR)); //if ($zcAR > 1) { // landscape $thumbnailH = round(max($sideY, $sideY * $zcAR / $imAR)); //echo '<pre>'; //var_dump($sideY); //var_dump($zcAR); //var_dump($imAR); //var_dump($thumbnailH); $commandline .= ' -thumbnail x' . $thumbnailH; //} else { // portrait or square // $thumbnailH = max($sideY, ($sideY * $zcAR) / $imAR); // $commandline .= ' -thumbnail '.$sideX.'x'.round($sideX / $zcAR); //} //echo '<pre>'; //var_dump($this->w); //var_dump($this->wp); //var_dump($this->wl); //var_dump($this->ws); //var_dump($wAll); //var_dump($side); //var_dump($sideX); //var_dump($sideY); //var_dump($zcAR); //var_dump($thumbnailH); //print_r($getimagesize); //echo '</pre>'; $commandline .= ' -gravity center'; if ($wAll > 0 && $hAll > 0) { $commandline .= ' -crop ' . $wAll . 'x' . $hAll . '+0+0'; } else { $commandline .= ' -crop ' . $side . 'x' . $side . '+0+0'; } $commandline .= ' +repage'; } elseif ($this->sw || $this->sh || $this->sx || $this->sy) { $commandline .= ' -crop ' . ($this->sw ? $this->sw : $this->source_width) . 'x' . ($this->sh ? $this->sh : $this->source_height) . '+' . $this->sx . '+' . $this->sy; // this is broken for aoe=1, but unsure how to fix. Send advice to info@silisoftware.com if ($this->w || $this->h) { $commandline .= ' -repage'; $commandline .= ' -thumbnail ' . $this->w . 'x' . $this->h; } } else { if ($this->iar && intval($this->w) > 0 && intval($this->h) > 0) { $commandline .= ' -thumbnail ' . $this->w . 'x' . $this->h . '!'; } else { //echo '<pre>'; //print_r($getimagesize); //echo '</pre>'; //echo $this->w.'x'.$this->h.'<br>'; $this->w = ($this->aoe || $this->far) && $this->w ? $this->w : ($this->w ? phpthumb_functions::nonempty_min($this->w, $getimagesize[0]) : ''); $this->h = ($this->aoe || $this->far) && $this->h ? $this->h : ($this->h ? phpthumb_functions::nonempty_min($this->h, $getimagesize[1]) : ''); //echo $this->w.'x'.$this->h.'<br>'; if ($this->w || $this->h) { $commandline .= ' -thumbnail ' . $this->w . 'x' . $this->h; } } } } } else { $this->DebugMessage('GetImageSize(' . $this->sourceFilename . ') failed', __FILE__, __LINE__); if ($this->w || $this->h) { $commandline .= ' -thumbnail ' . $this->w . 'x' . $this->h; if ($this->iar && intval($this->w) > 0 && intval($this->h) > 0) { $commandline .= '!'; } } } foreach ($this->fltr as $filterkey => $filtercommand) { @(list($command, $parameter) = explode('|', $filtercommand, 2)); switch ($command) { case 'brit': if ($this->ImageMagickSwitchAvailable('modulate')) { $commandline .= ' -modulate ' . (100 + $parameter) . ',100,100'; unset($this->fltr[$filterkey]); } break; case 'cont': if ($this->ImageMagickSwitchAvailable('contrast')) { $contDiv10 = round($parameter / 10); if ($contDiv10 > 0) { for ($i = 0; $i < $contDiv10; $i++) { $commandline .= ' -contrast'; // increase contrast by 10% } } elseif ($contDiv10 < 0) { for ($i = $contDiv10; $i < 0; $i++) { $commandline .= ' +contrast'; // decrease contrast by 10% } } else { // do nothing } unset($this->fltr[$filterkey]); } break; case 'ds': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { if ($parameter == 100) { $commandline .= ' -colorspace GRAY -modulate 100,0,100'; } else { $commandline .= ' -modulate 100,' . (100 - $parameter) . ',100'; } unset($this->fltr[$filterkey]); } break; case 'sat': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { if ($parameter == -100) { $commandline .= ' -colorspace GRAY -modulate 100,0,100'; } else { $commandline .= ' -modulate 100,' . (100 + $parameter) . ',100'; } unset($this->fltr[$filterkey]); } break; case 'gray': if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) { $commandline .= ' -colorspace GRAY -modulate 100,0,100'; //$commandline .= ' -colorspace GRAY'; unset($this->fltr[$filterkey]); } break; case 'clr': if ($this->ImageMagickSwitchAvailable(array('fill', 'colorize'))) { @(list($amount, $color) = explode('|', $parameter)); $commandline .= ' -fill #' . $color . ' -colorize ' . $amount; } break; case 'sep': if ($this->ImageMagickSwitchAvailable('sepia-tone')) { @(list($amount, $color) = explode('|', $parameter)); $amount = $amount ? $amount : 80; if (!$color) { $commandline .= ' -sepia-tone ' . $amount . '%'; unset($this->fltr[$filterkey]); } } break; case 'gam': if ($this->ImageMagickSwitchAvailable('gamma')) { $commandline .= ' -gamma ' . $parameter; unset($this->fltr[$filterkey]); } break; case 'neg': if ($this->ImageMagickSwitchAvailable('negate')) { $commandline .= ' -negate'; unset($this->fltr[$filterkey]); } break; case 'th': if ($this->ImageMagickSwitchAvailable(array('threshold', 'dither', 'monochrome'))) { $commandline .= ' -threshold ' . round($parameter / 2.55) . '% -dither -monochrome'; unset($this->fltr[$filterkey]); } break; case 'rcd': if ($this->ImageMagickSwitchAvailable(array('colors', 'dither'))) { @(list($colors, $dither) = explode('|', $parameter)); $colors = $colors ? (int) $colors : 256; $dither = strlen($dither) > 0 ? (bool) $dither : true; $commandline .= ' -colors ' . max($colors, 8); // ImageMagick will otherwise fail with "cannot quantize to fewer than 8 colors" $commandline .= $dither ? ' -dither' : ' +dither'; unset($this->fltr[$filterkey]); } break; case 'flip': if ($this->ImageMagickSwitchAvailable(array('flip', 'flop'))) { if (strpos(strtolower($parameter), 'x') !== false) { $commandline .= ' -flop'; } if (strpos(strtolower($parameter), 'y') !== false) { $commandline .= ' -flip'; } unset($this->fltr[$filterkey]); } break; case 'edge': if ($this->ImageMagickSwitchAvailable('edge')) { $parameter = $parameter ? $parameter : 2; $commandline .= ' -edge ' . ($parameter ? $parameter : 1); unset($this->fltr[$filterkey]); } break; case 'emb': if ($this->ImageMagickSwitchAvailable(array('emboss', 'negate'))) { $parameter = $parameter ? $parameter : 2; $commandline .= ' -emboss ' . $parameter; if ($parameter < 2) { $commandline .= ' -negate'; // ImageMagick negates the image for some reason with '-emboss 1'; } unset($this->fltr[$filterkey]); } break; case 'lvl': if ($this->ImageMagickSwitchAvailable(array('normalize', 'level'))) { @(list($band, $min, $max) = explode('|', $parameter)); $band = $band ? $band : '*'; $min = strlen($min) > 0 ? $min : '-1'; $max = strlen($max) > 0 ? $max : '-1'; if ($band == '*') { if ($min == -1 && $max == -1) { $commandline .= ' -normalize'; unset($this->fltr[$filterkey]); } elseif ($min == -1 || $max == -1) { // } else { $commandline .= ' -level ' . $min . '%,' . $max . '%'; unset($this->fltr[$filterkey]); } } } break; case 'blur': if ($this->ImageMagickSwitchAvailable('blur')) { @(list($radius) = explode('|', $parameter)); $radius = $radius ? $radius : 1; $commandline .= ' -blur ' . $radius; unset($this->fltr[$filterkey]); } break; case 'gblr': if ($this->ImageMagickSwitchAvailable('gaussian')) { @(list($radius) = explode('|', $parameter)); $radius = $radius ? $radius : 1; $commandline .= ' -gaussian ' . $radius; unset($this->fltr[$filterkey]); } break; case 'usm': if ($this->ImageMagickSwitchAvailable('unsharp')) { @(list($amount, $radius, $threshold) = explode('|', $parameter)); $amount = $amount ? $amount : 80; $radius = $radius ? $radius : 0.5; $threshold = strlen($threshold) ? $threshold : 3; $commandline .= ' -unsharp ' . number_format($radius * 2 - 1, 2) . 'x1+' . number_format($amount / 100, 2) . '+' . number_format($threshold / 100, 2); unset($this->fltr[$filterkey]); } break; case 'bord': if ($this->ImageMagickSwitchAvailable(array('border', 'bordercolor', 'thumbnail', 'crop'))) { if (!$this->zc) { @(list($width, $rX, $rY, $color) = explode('|', $parameter)); if ($width && !$rX && !$rY) { if (!phpthumb_functions::IsHexColor($color)) { $color = $this->bc ? $this->bc : '000000'; } $commandline .= ' -border ' . $width . ' -bordercolor "#' . $color . '"'; if (ereg(' \\-crop ([0-9]+)x([0-9]+)\\+0\\+0 ', $commandline, $matches)) { $commandline = str_replace(' -crop ' . $matches[1] . 'x' . $matches[2] . '+0+0 ', ' -crop ' . ($matches[1] - 2 * $width) . 'x' . ($matches[2] - 2 * $width) . '+0+0 ', $commandline); } elseif (ereg(' \\-thumbnail ([0-9]+)x([0-9]+) ', $commandline, $matches)) { $commandline = str_replace(' -thumbnail ' . $matches[1] . 'x' . $matches[2] . ' ', ' -thumbnail ' . ($matches[1] - 2 * $width) . 'x' . ($matches[2] - 2 * $width) . ' ', $commandline); } unset($this->fltr[$filterkey]); } } } break; case 'crop': break; case 'sblr': break; case 'mean': break; case 'smth': break; case 'bvl': break; case 'wmi': break; case 'wmt': break; case 'over': break; case 'wb': break; case 'hist': break; case 'fram': break; case 'drop': break; case 'mask': break; case 'elip': break; case 'ric': break; } if (!isset($this->fltr[$filterkey])) { $this->DebugMessage('Processed $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); } else { $this->DebugMessage('Skipping $this->fltr[' . $filterkey . '] (' . $filtercommand . ') with ImageMagick', __FILE__, __LINE__); } } $this->DebugMessage('Remaining $this->fltr after ImageMagick: (' . $this->phpThumbDebugVarDump($this->fltr) . ')', __FILE__, __LINE__); if (eregi('jpe?g', $outputFormat) && $this->q) { if ($this->ImageMagickSwitchAvailable(array('quality', 'interlace'))) { $commandline .= ' -quality ' . $this->thumbnailQuality; if ($this->config_output_interlace) { // causes weird things with animated GIF... leave for JPEG only $commandline .= ' -interlace line '; // Use Line or Plane to create an interlaced PNG or GIF or progressive JPEG image } } } $commandline .= ' "' . str_replace('/', DIRECTORY_SEPARATOR, $this->sourceFilename) . ($outputFormat == 'gif' ? '' : '[0]') . '"'; // [0] means first frame of (GIF) animation, can be ignored $commandline .= ' ' . $outputFormat . ':"' . $IMtempfilename . '"'; $commandline .= ' 2>&1'; $this->DebugMessage('ImageMagick called as (' . $commandline . ')', __FILE__, __LINE__); $IMresult = phpthumb_functions::SafeExec($commandline); //echo '<pre>'; //var_dump($commandline); ////var_dump($ImageCreateFunction); ////var_dump($IMresult); //echo '</pre>'; //exit; clearstatcache(); if (!@file_exists($IMtempfilename) || !@filesize($IMtempfilename)) { $this->DebugMessage('ImageMagick failed with message (' . $IMresult . ')', __FILE__, __LINE__); if ($this->iswindows && !$IMresult) { $this->DebugMessage('Check to make sure that PHP has read+write permissions to "' . dirname($IMtempfilename) . '"', __FILE__, __LINE__); } } else { $this->IMresizedData = file_get_contents($IMtempfilename); if (function_exists(@$ImageCreateFunction) && ($this->gdimg_source = @$ImageCreateFunction($IMtempfilename))) { //header('Content-Type: image/png'); //ImageSaveAlpha($this->gdimg_source, true); //ImagePNG($this->gdimg_source); //exit; $this->source_width = ImageSX($this->gdimg_source); $this->source_height = ImageSY($this->gdimg_source); $this->DebugMessage('ImageMagickThumbnailToGD::' . $ImageCreateFunction . '() succeeded, $this->gdimg_source is now (' . $this->source_width . 'x' . $this->source_height . ')', __FILE__, __LINE__); $this->DebugMessage('ImageMagickThumbnailToGD() returning $IMresizedData (' . strlen($this->IMresizedData) . ' bytes)', __FILE__, __LINE__); } else { $this->useRawIMoutput = true; $this->DebugMessage('$this->useRawIMoutput set to TRUE because ' . @$ImageCreateFunction . '(' . $IMtempfilename . ') failed', __FILE__, __LINE__); } @unlink($IMtempfilename); return true; } unlink($IMtempfilename); } else { $this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpThumb_tempnam() failed', __FILE__, __LINE__); } } else { $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__); } $this->useRawIMoutput = false; return false; }