42 if ( !$dstPath && $checkDstPath ) {
43 # No output path available, client side scaling only
51 } elseif ( function_exists(
'imagecreatetruecolor' ) ) {
53 } elseif ( class_exists(
'Imagick' ) ) {
65 return "interlaced-{$res}";
72 $remainder = preg_replace(
'/^interlaced-/',
'', $str );
73 $params = parent::parseParamString( $remainder );
77 $params[
'interlace'] = $str !== $remainder;
82 if ( $name ===
'interlace' ) {
85 return parent::validateParam( $name,
$value );
99 $mimeType =
$image->getMimeType();
100 $interlace = isset(
$params[
'interlace'] ) &&
$params[
'interlace']
103 $params[
'interlace'] = $interlace;
114 switch ( $pixelFormat ) {
116 return [
'1x1',
'1x1',
'1x1' ];
118 return [
'2x1',
'1x1',
'1x1' ];
120 return [
'2x2',
'1x1',
'1x1' ];
122 throw new MWException(
'Invalid pixel format for JPEG output' );
143 $animation_post = [];
147 if (
$params[
'mimeType'] ==
'image/jpeg' ) {
149 $quality = [
'-quality', $qualityVal ?:
'80' ];
151 $animation_post = [
'-interlace',
'JPEG' ];
153 # Sharpening, see T8193
162 $decoderHint = [
'-define',
"jpeg:size={$params['physicalDimensions']}" ];
166 $subsampling = [
'-sampling-factor', implode(
',', $factors ) ];
168 } elseif (
$params[
'mimeType'] ==
'image/png' ) {
169 $quality = [
'-quality',
'95' ];
171 $animation_post = [
'-interlace',
'PNG' ];
173 } elseif (
$params[
'mimeType'] ==
'image/webp' ) {
174 $quality = [
'-quality',
'95' ];
175 } elseif (
$params[
'mimeType'] ==
'image/gif' ) {
182 $animation_pre = [
'-coalesce' ];
186 $animation_post = [
'-fuzz',
'5%',
'-layers',
'optimizeTransparency' ];
191 $animation_post[] =
'-interlace';
192 $animation_post[] =
'GIF';
194 } elseif (
$params[
'mimeType'] ==
'image/x-xcf' ) {
202 '-background',
'transparent',
204 '-background',
'white',
206 Wikimedia\suppressWarnings();
208 Wikimedia\restoreWarnings();
210 && isset( $xcfMeta[
'colorType'] )
211 && $xcfMeta[
'colorType'] ===
'greyscale-alpha'
216 $channelOnly = [
'-channel',
'R',
'-separate' ];
217 $animation_pre = array_merge( $animation_pre, $channelOnly );
222 $env = [
'OMP_NUM_THREADS' => 1 ];
230 $cmd = call_user_func_array(
'wfEscapeShellArg', array_merge(
235 [
'-background',
'white' ],
242 [
'-thumbnail',
"{$width}x{$height}!" ],
248 [
'+set',
'Thumb::URI' ],
251 [
'-rotate',
"-$rotation" ],
256 wfDebug( __METHOD__ .
": running ImageMagick: $cmd\n" );
266 return false; # No error
283 $im->readImage(
$params[
'srcPath'] );
285 if (
$params[
'mimeType'] ==
'image/jpeg' ) {
293 $im->sharpenImage( $radius, $sigma );
296 $im->setCompressionQuality( $qualityVal ?: 80 );
298 $im->setInterlaceScheme( Imagick::INTERLACE_JPEG );
302 $im->setSamplingFactors( $factors );
304 } elseif (
$params[
'mimeType'] ==
'image/png' ) {
305 $im->setCompressionQuality( 95 );
307 $im->setInterlaceScheme( Imagick::INTERLACE_PNG );
309 } elseif (
$params[
'mimeType'] ==
'image/gif' ) {
313 $im->setImageScene( 0 );
316 $im = $im->coalesceImages();
319 $v = Imagick::getVersion();
320 preg_match(
'/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v[
'versionString'], $v );
322 if (
$params[
'interlace'] && version_compare( $v[1],
'6.3.4' ) >= 0 ) {
323 $im->setInterlaceScheme( Imagick::INTERLACE_GIF );
330 $im->setImageBackgroundColor(
new ImagickPixel(
'white' ) );
333 foreach ( $im as $i => $frame ) {
334 if ( !$frame->thumbnailImage( $width, $height,
false ) ) {
338 $im->setImageDepth( 8 );
341 if ( !$im->rotateImage(
new ImagickPixel(
'white' ), 360 - $rotation ) ) {
347 wfDebug( __METHOD__ .
": Writing animated thumbnail\n" );
349 $result = $im->writeImages(
$params[
'dstPath'],
true );
351 $result = $im->writeImage(
$params[
'dstPath'] );
355 "Unable to write thumbnail to {$params['dstPath']}" );
357 }
catch ( ImagickException
$e ) {
373 # Use a custom convert command
376 # Variables: %s %d %w %h
380 $cmd = str_replace(
'%s', $src, str_replace(
'%d', $dst, $cmd ) ); # Filenames
383 wfDebug( __METHOD__ .
": Running custom convert command $cmd\n" );
393 return false; # No error
405 # Use PHP's builtin GD library functions.
406 # First find out what kind of file this is, and select the correct
407 # input routine for this.
410 'image/gif' => [
'imagecreatefromgif',
'palette',
false,
'imagegif' ],
411 'image/jpeg' => [
'imagecreatefromjpeg',
'truecolor',
true,
412 [ __CLASS__,
'imageJpegWrapper' ] ],
413 'image/png' => [
'imagecreatefrompng',
'bits',
false,
'imagepng' ],
414 'image/vnd.wap.wbmp' => [
'imagecreatefromwbmp',
'palette',
false,
'imagewbmp' ],
415 'image/xbm' => [
'imagecreatefromxbm',
'palette',
false,
'imagexbm' ],
418 if ( !isset( $typemap[
$params[
'mimeType']] ) ) {
419 $err =
'Image type not supported';
421 $errMsg =
wfMessage(
'thumbnail_image-type' )->text();
425 list( $loader, $colorStyle, $useQuality, $saveType ) = $typemap[
$params[
'mimeType']];
427 if ( !function_exists( $loader ) ) {
428 $err =
"Incomplete GD library configuration: missing function $loader";
430 $errMsg =
wfMessage(
'thumbnail_gd-library', $loader )->text();
435 if ( !file_exists(
$params[
'srcPath'] ) ) {
436 $err =
"File seems to be missing: {$params['srcPath']}";
438 $errMsg =
wfMessage(
'thumbnail_image-missing',
$params[
'srcPath'] )->text();
443 if ( filesize(
$params[
'srcPath'] ) === 0 ) {
444 $err =
"Image file size seems to be zero.";
446 $errMsg =
wfMessage(
'thumbnail_image-size-zero',
$params[
'srcPath'] )->text();
451 $src_image = call_user_func( $loader,
$params[
'srcPath'] );
453 $rotation = function_exists(
'imagerotate' ) && !isset(
$params[
'disableRotation'] ) ?
457 $dst_image = imagecreatetruecolor( $width, $height );
461 $background = imagecolorallocate( $dst_image, 0, 0, 0 );
462 imagecolortransparent( $dst_image, $background );
463 imagealphablending( $dst_image,
false );
465 if ( $colorStyle ==
'palette' ) {
468 imagecopyresized( $dst_image, $src_image,
471 imagesx( $src_image ), imagesy( $src_image ) );
473 imagecopyresampled( $dst_image, $src_image,
476 imagesx( $src_image ), imagesy( $src_image ) );
479 if ( $rotation % 360 != 0 && $rotation % 90 == 0 ) {
480 $rot_image = imagerotate( $dst_image, $rotation, 0 );
481 imagedestroy( $dst_image );
482 $dst_image = $rot_image;
485 imagesavealpha( $dst_image,
true );
487 $funcParams = [ $dst_image,
$params[
'dstPath'] ];
488 if ( $useQuality && isset(
$params[
'quality'] ) ) {
489 $funcParams[] =
$params[
'quality'];
491 call_user_func_array( $saveType, $funcParams );
493 imagedestroy( $dst_image );
494 imagedestroy( $src_image );
496 return false; # No error
504 imageinterlace( $dst_image );
505 imagejpeg( $dst_image, $thumbPath, $quality );
517 # ImageMagick supports autorotation
520 # Imagick::rotateImage
523 # GD's imagerotate function is used to rotate images, but not
524 # all precompiled PHP versions have that function
525 return function_exists(
'imagerotate' );
527 # Other scalers don't support rotation
567 wfDebug( __METHOD__ .
": running ImageMagick: $cmd\n" );
579 $im->readImage(
$params[
'srcPath'] );
580 if ( !$im->rotateImage(
new ImagickPixel(
'white' ), 360 - $rotation ) ) {
582 "Error rotating $rotation degrees" );
584 $result = $im->writeImage(
$params[
'dstPath'] );
587 "Unable to write image to {$params['dstPath']}" );
593 "$scaler rotation not implemented" );
unserialize( $serialized)
$wgCustomConvertCommand
Use another resizing converter, e.g.
$wgMaxInterlacingAreas
Array of max pixel areas for interlacing per MIME type.
$wgUseImageResize
Whether to enable server-side image thumbnailing.
$wgEnableAutoRotation
If set to true, images that contain certain the exif orientation tag will be rotated accordingly.
$wgImageMagickTempDir
Temporary directory used for ImageMagick.
$wgSharpenReductionThreshold
Reduction in linear dimensions below which sharpening will be enabled.
$wgJpegPixelFormat
At default setting of 'yuv420', JPEG thumbnails will use 4:2:0 chroma subsampling to reduce file size...
$wgSharpenParameter
Sharpening parameter to ImageMagick.
$wgMaxAnimatedGifArea
Force thumbnailing of animated GIFs above this size to a single frame instead of an animated thumbnai...
$wgUseImageMagick
Resizing can be done using PHP's internal image libraries or using ImageMagick or another third-party...
$wgImageMagickConvertCommand
The convert command shipped with ImageMagick.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfEscapeShellArg()
Version of escapeshellarg() that works better on Windows.
wfShellExecWithStderr( $cmd, &$retval=null, $environ=[], $limits=[])
Execute a shell command, returning both stdout and stderr.
Generic handler for bitmap images.
canRotate()
Returns whether the current scaler supports rotation (im and gd do)
transformImageMagick( $image, $params)
Transform an image using ImageMagick.
getScalerType( $dstPath, $checkDstPath=true)
Returns which scaler type should be used.
imageMagickSubsampling( $pixelFormat)
Get ImageMagick subsampling factors for the target JPEG pixel format.
transformCustom( $image, $params)
Transform an image using a custom command.
makeParamString( $params)
Merge a parameter array into a string appropriate for inclusion in filenames.
transformGd( $image, $params)
Transform an image using the built in GD library.
parseParamString( $str)
Parse a param string made with makeParamString back into an array.
normaliseParams( $image, &$params)
transformImageMagickExt( $image, $params)
Transform an image using the Imagick PHP extension.
validateParam( $name, $value)
Validate a thumbnail parameter at parse time.
static imageJpegWrapper( $dst_image, $thumbPath, $quality=95)
Callback for transformGd when transforming jpeg images.
getImageArea( $image)
Function that returns the number of pixels to be thumbnailed.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account incomplete not yet checked for validity & $retval
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable modifiable after all normalizations have been except for the $wgMaxImageArea check $image
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "<div ...>$1</div>"). - flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException':Called before an exception(or PHP error) is logged. This is meant for integration with external error aggregation services
returning false will NOT prevent logging $e