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' );
144 $animation_post = [];
148 if (
$params[
'mimeType'] ==
'image/jpeg' ) {
152 $animation_post = [
'-interlace',
'JPEG' ];
154 # Sharpening, see T8193
163 $decoderHint = [
'-define',
"jpeg:size={$params['physicalDimensions']}" ];
167 $subsampling = [
'-sampling-factor', implode(
',', $factors ) ];
169 } elseif (
$params[
'mimeType'] ==
'image/png' ) {
170 $quality = [
'-quality',
'95' ];
172 $animation_post = [
'-interlace',
'PNG' ];
174 } elseif (
$params[
'mimeType'] ==
'image/webp' ) {
175 $quality = [
'-quality',
'95' ];
176 } elseif (
$params[
'mimeType'] ==
'image/gif' ) {
183 $animation_pre = [
'-coalesce' ];
187 $animation_post = [
'-fuzz',
'5%',
'-layers',
'optimizeTransparency' ];
192 $animation_post[] =
'-interlace';
193 $animation_post[] =
'GIF';
195 } elseif (
$params[
'mimeType'] ==
'image/x-xcf' ) {
203 '-background',
'transparent',
205 '-background',
'white',
207 Wikimedia\suppressWarnings();
209 Wikimedia\restoreWarnings();
211 && isset( $xcfMeta[
'colorType'] )
212 && $xcfMeta[
'colorType'] ===
'greyscale-alpha'
217 $channelOnly = [
'-channel',
'R',
'-separate' ];
218 $animation_pre = array_merge( $animation_pre, $channelOnly );
223 $env = [
'OMP_NUM_THREADS' => 1 ];
236 [
'-background',
'white' ],
243 [
'-thumbnail',
"{$width}x{$height}!" ],
249 [
'+set',
'Thumb::URI' ],
252 [
'-rotate',
"-$rotation" ],
257 wfDebug( __METHOD__ .
": running ImageMagick: $cmd\n" );
267 return false; # No error
284 $im->readImage(
$params[
'srcPath'] );
286 if (
$params[
'mimeType'] ==
'image/jpeg' ) {
294 $im->sharpenImage( $radius, $sigma );
299 $im->setInterlaceScheme( Imagick::INTERLACE_JPEG );
303 $im->setSamplingFactors( $factors );
305 } elseif (
$params[
'mimeType'] ==
'image/png' ) {
306 $im->setCompressionQuality( 95 );
308 $im->setInterlaceScheme( Imagick::INTERLACE_PNG );
310 } elseif (
$params[
'mimeType'] ==
'image/gif' ) {
314 $im->setImageScene( 0 );
317 $im = $im->coalesceImages();
320 $v = Imagick::getVersion();
321 preg_match(
'/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v[
'versionString'], $v );
323 if (
$params[
'interlace'] && version_compare( $v[1],
'6.3.4' ) >= 0 ) {
324 $im->setInterlaceScheme( Imagick::INTERLACE_GIF );
331 $im->setImageBackgroundColor(
new ImagickPixel(
'white' ) );
334 foreach ( $im as $i => $frame ) {
335 if ( !$frame->thumbnailImage( $width, $height,
false ) ) {
339 $im->setImageDepth( 8 );
342 if ( !$im->rotateImage(
new ImagickPixel(
'white' ), 360 - $rotation ) ) {
348 wfDebug( __METHOD__ .
": Writing animated thumbnail\n" );
350 $result = $im->writeImages(
$params[
'dstPath'],
true );
352 $result = $im->writeImage(
$params[
'dstPath'] );
356 "Unable to write thumbnail to {$params['dstPath']}" );
358 }
catch ( ImagickException
$e ) {
374 # Use a custom convert command
377 # Variables: %s %d %w %h
381 $cmd = str_replace(
'%s', $src, str_replace(
'%d', $dst, $cmd ) ); # Filenames
384 wfDebug( __METHOD__ .
": Running custom convert command $cmd\n" );
394 return false; # No error
406 # Use PHP's builtin GD library functions.
407 # First find out what kind of file this is, and select the correct
408 # input routine for this.
411 'image/gif' => [
'imagecreatefromgif',
'palette',
false,
'imagegif' ],
412 'image/jpeg' => [
'imagecreatefromjpeg',
'truecolor',
true,
413 [ __CLASS__,
'imageJpegWrapper' ] ],
414 'image/png' => [
'imagecreatefrompng',
'bits',
false,
'imagepng' ],
415 'image/vnd.wap.wbmp' => [
'imagecreatefromwbmp',
'palette',
false,
'imagewbmp' ],
416 'image/xbm' => [
'imagecreatefromxbm',
'palette',
false,
'imagexbm' ],
419 if ( !isset( $typemap[
$params[
'mimeType']] ) ) {
420 $err =
'Image type not supported';
422 $errMsg =
wfMessage(
'thumbnail_image-type' )->text();
426 list( $loader, $colorStyle, $useQuality, $saveType ) = $typemap[
$params[
'mimeType']];
428 if ( !function_exists( $loader ) ) {
429 $err =
"Incomplete GD library configuration: missing function $loader";
431 $errMsg =
wfMessage(
'thumbnail_gd-library', $loader )->text();
436 if ( !file_exists(
$params[
'srcPath'] ) ) {
437 $err =
"File seems to be missing: {$params['srcPath']}";
439 $errMsg =
wfMessage(
'thumbnail_image-missing',
$params[
'srcPath'] )->text();
444 if ( filesize(
$params[
'srcPath'] ) === 0 ) {
445 $err =
"Image file size seems to be zero.";
447 $errMsg =
wfMessage(
'thumbnail_image-size-zero',
$params[
'srcPath'] )->text();
452 $src_image = $loader(
$params[
'srcPath'] );
454 $rotation = function_exists(
'imagerotate' ) && !isset(
$params[
'disableRotation'] ) ?
458 $dst_image = imagecreatetruecolor( $width, $height );
462 $background = imagecolorallocate( $dst_image, 0, 0, 0 );
463 imagecolortransparent( $dst_image, $background );
464 imagealphablending( $dst_image,
false );
466 if ( $colorStyle ==
'palette' ) {
469 imagecopyresized( $dst_image, $src_image,
472 imagesx( $src_image ), imagesy( $src_image ) );
474 imagecopyresampled( $dst_image, $src_image,
477 imagesx( $src_image ), imagesy( $src_image ) );
480 if ( $rotation % 360 != 0 && $rotation % 90 == 0 ) {
481 $rot_image = imagerotate( $dst_image, $rotation, 0 );
482 imagedestroy( $dst_image );
483 $dst_image = $rot_image;
486 imagesavealpha( $dst_image,
true );
488 $funcParams = [ $dst_image,
$params[
'dstPath'] ];
489 if ( $useQuality && isset(
$params[
'quality'] ) ) {
490 $funcParams[] =
$params[
'quality'];
492 $saveType( ...$funcParams );
494 imagedestroy( $dst_image );
495 imagedestroy( $src_image );
497 return false; # No error
511 if ( $quality ===
null ) {
515 imageinterlace( $dst_image );
516 imagejpeg( $dst_image, $thumbPath, $quality );
528 # ImageMagick supports autorotation
531 # Imagick::rotateImage
534 # GD's imagerotate function is used to rotate images, but not
535 # all precompiled PHP versions have that function
536 return function_exists(
'imagerotate' );
538 # Other scalers don't support rotation
578 wfDebug( __METHOD__ .
": running ImageMagick: $cmd\n" );
590 $im->readImage(
$params[
'srcPath'] );
591 if ( !$im->rotateImage(
new ImagickPixel(
'white' ), 360 - $rotation ) ) {
593 "Error rotating $rotation degrees" );
595 $result = $im->writeImage(
$params[
'dstPath'] );
598 "Unable to write image to {$params['dstPath']}" );
604 "$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.
$wgJpegQuality
When scaling a JPEG thumbnail, this is the quality we request from the backend.
$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(... $args)
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)
static imageJpegWrapper( $dst_image, $thumbPath, $quality=null)
Callback for transformGd when transforming jpeg images.
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.
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 use $formDescriptor instead 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