MediaWiki  master
BitmapHandler.php
Go to the documentation of this file.
1 <?php
25 
33 
43  protected function getScalerType( $dstPath, $checkDstPath = true ) {
45 
46  if ( !$dstPath && $checkDstPath ) {
47  # No output path available, client side scaling only
48  $scaler = 'client';
49  } elseif ( !$wgUseImageResize ) {
50  $scaler = 'client';
51  } elseif ( $wgUseImageMagick ) {
52  $scaler = 'im';
53  } elseif ( $wgCustomConvertCommand ) {
54  $scaler = 'custom';
55  } elseif ( function_exists( 'imagecreatetruecolor' ) ) {
56  $scaler = 'gd';
57  } elseif ( class_exists( 'Imagick' ) ) {
58  $scaler = 'imext';
59  } else {
60  $scaler = 'client';
61  }
62 
63  return $scaler;
64  }
65 
70  public function makeParamString( $params ) {
71  $res = parent::makeParamString( $params );
72  if ( isset( $params['interlace'] ) && $params['interlace'] ) {
73  return "interlaced-{$res}";
74  } else {
75  return $res;
76  }
77  }
78 
83  public function parseParamString( $str ) {
84  $remainder = preg_replace( '/^interlaced-/', '', $str );
85  $params = parent::parseParamString( $remainder );
86  if ( $params === false ) {
87  return false;
88  }
89  $params['interlace'] = $str !== $remainder;
90  return $params;
91  }
92 
97  public function validateParam( $name, $value ) {
98  if ( $name === 'interlace' ) {
99  return $value === false || $value === true;
100  } else {
101  return parent::validateParam( $name, $value );
102  }
103  }
104 
111  public function normaliseParams( $image, &$params ) {
112  global $wgMaxInterlacingAreas;
113  if ( !parent::normaliseParams( $image, $params ) ) {
114  return false;
115  }
116  $mimeType = $image->getMimeType();
117  $interlace = isset( $params['interlace'] ) && $params['interlace']
118  && isset( $wgMaxInterlacingAreas[$mimeType] )
119  && $this->getImageArea( $image ) <= $wgMaxInterlacingAreas[$mimeType];
120  $params['interlace'] = $interlace;
121  return true;
122  }
123 
130  protected function imageMagickSubsampling( $pixelFormat ) {
131  switch ( $pixelFormat ) {
132  case 'yuv444':
133  return [ '1x1', '1x1', '1x1' ];
134  case 'yuv422':
135  return [ '2x1', '1x1', '1x1' ];
136  case 'yuv420':
137  return [ '2x2', '1x1', '1x1' ];
138  default:
139  throw new MWException( 'Invalid pixel format for JPEG output' );
140  }
141  }
142 
152  protected function transformImageMagick( $image, $params ) {
153  # use ImageMagick
157 
158  $quality = [];
159  $sharpen = [];
160  $scene = false;
161  $animation_pre = [];
162  $animation_post = [];
163  $decoderHint = [];
164  $subsampling = [];
165 
166  if ( $params['mimeType'] == 'image/jpeg' ) {
167  $qualityVal = isset( $params['quality'] ) ? (string)$params['quality'] : null;
168  $quality = [ '-quality', $qualityVal ?: (string)$wgJpegQuality ]; // 80% by default
169  if ( $params['interlace'] ) {
170  $animation_post = [ '-interlace', 'JPEG' ];
171  }
172  # Sharpening, see T8193
173  if ( ( $params['physicalWidth'] + $params['physicalHeight'] )
174  / ( $params['srcWidth'] + $params['srcHeight'] )
176  ) {
177  $sharpen = [ '-sharpen', $wgSharpenParameter ];
178  }
179 
180  // JPEG decoder hint to reduce memory, available since IM 6.5.6-2
181  $decoderHint = [ '-define', "jpeg:size={$params['physicalDimensions']}" ];
182 
183  if ( $wgJpegPixelFormat ) {
184  $factors = $this->imageMagickSubsampling( $wgJpegPixelFormat );
185  $subsampling = [ '-sampling-factor', implode( ',', $factors ) ];
186  }
187  } elseif ( $params['mimeType'] == 'image/png' ) {
188  $quality = [ '-quality', '95' ]; // zlib 9, adaptive filtering
189  if ( $params['interlace'] ) {
190  $animation_post = [ '-interlace', 'PNG' ];
191  }
192  } elseif ( $params['mimeType'] == 'image/webp' ) {
193  $quality = [ '-quality', '95' ]; // zlib 9, adaptive filtering
194  } elseif ( $params['mimeType'] == 'image/gif' ) {
195  if ( $this->getImageArea( $image ) > $wgMaxAnimatedGifArea ) {
196  // Extract initial frame only; we're so big it'll
197  // be a total drag. :P
198  $scene = 0;
199  } elseif ( $this->isAnimatedImage( $image ) ) {
200  // Coalesce is needed to scale animated GIFs properly (T3017).
201  $animation_pre = [ '-coalesce' ];
202 
203  // We optimize the output, but -optimize is broken,
204  // use optimizeTransparency instead (T13822). Version >= IM 6.3.5
205  $animation_post = [ '-fuzz', '5%', '-layers', 'optimizeTransparency' ];
206  }
207  if ( $params['interlace'] && !$this->isAnimatedImage( $image ) ) {
208  // Version >= IM 6.3.4
209  // interlacing animated GIFs is a bad idea
210  $animation_post[] = '-interlace';
211  $animation_post[] = 'GIF';
212  }
213  } elseif ( $params['mimeType'] == 'image/x-xcf' ) {
214  // Before merging layers, we need to set the background
215  // to be transparent to preserve alpha, as -layers merge
216  // merges all layers on to a canvas filled with the
217  // background colour. After merging we reset the background
218  // to be white for the default background colour setting
219  // in the PNG image (which is used in old IE)
220  $animation_pre = [
221  '-background', 'transparent',
222  '-layers', 'merge',
223  '-background', 'white',
224  ];
225  }
226 
227  // Use one thread only, to avoid deadlock bugs on OOM
228  $env = [ 'OMP_NUM_THREADS' => 1 ];
229  if ( strval( $wgImageMagickTempDir ) !== '' ) {
230  $env['MAGICK_TMPDIR'] = $wgImageMagickTempDir;
231  }
232 
233  $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
234  list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
235 
236  $cmd = Shell::escape( ...array_merge(
238  $quality,
239  // Specify white background color, will be used for transparent images
240  // in Internet Explorer/Windows instead of default black.
241  [ '-background', 'white' ],
242  $decoderHint,
243  [ $this->escapeMagickInput( $params['srcPath'], $scene ) ],
244  $animation_pre,
245  // For the -thumbnail option a "!" is needed to force exact size,
246  // or ImageMagick may decide your ratio is wrong and slice off
247  // a pixel.
248  [ '-thumbnail', "{$width}x{$height}!" ],
249  // Add the source url as a comment to the thumb, but don't add the flag if there's no comment
250  ( $params['comment'] !== ''
251  ? [ '-set', 'comment', $this->escapeMagickProperty( $params['comment'] ) ]
252  : [] ),
253  // T108616: Avoid exposure of local file path
254  [ '+set', 'Thumb::URI' ],
255  [ '-depth', 8 ],
256  $sharpen,
257  [ '-rotate', "-$rotation" ],
258  $subsampling,
259  $animation_post,
260  [ $this->escapeMagickOutput( $params['dstPath'] ) ] ) );
261 
262  wfDebug( __METHOD__ . ": running ImageMagick: $cmd" );
263  $retval = 0;
264  $err = wfShellExecWithStderr( $cmd, $retval, $env );
265 
266  if ( $retval !== 0 ) {
267  $this->logErrorForExternalProcess( $retval, $err, $cmd );
268 
269  return $this->getMediaTransformError( $params, "$err\nError code: $retval" );
270  }
271 
272  return false; # No error
273  }
274 
283  protected function transformImageMagickExt( $image, $params ) {
286 
287  try {
288  $im = new Imagick();
289  $im->readImage( $params['srcPath'] );
290 
291  if ( $params['mimeType'] == 'image/jpeg' ) {
292  // Sharpening, see T8193
293  if ( ( $params['physicalWidth'] + $params['physicalHeight'] )
294  / ( $params['srcWidth'] + $params['srcHeight'] )
296  ) {
297  // Hack, since $wgSharpenParameter is written specifically for the command line convert
298  list( $radius, $sigma ) = explode( 'x', $wgSharpenParameter );
299  $im->sharpenImage( $radius, $sigma );
300  }
301  $qualityVal = isset( $params['quality'] ) ? (string)$params['quality'] : null;
302  $im->setCompressionQuality( $qualityVal ?: $wgJpegQuality );
303  if ( $params['interlace'] ) {
304  $im->setInterlaceScheme( Imagick::INTERLACE_JPEG );
305  }
306  if ( $wgJpegPixelFormat ) {
307  $factors = $this->imageMagickSubsampling( $wgJpegPixelFormat );
308  $im->setSamplingFactors( $factors );
309  }
310  } elseif ( $params['mimeType'] == 'image/png' ) {
311  $im->setCompressionQuality( 95 );
312  if ( $params['interlace'] ) {
313  $im->setInterlaceScheme( Imagick::INTERLACE_PNG );
314  }
315  } elseif ( $params['mimeType'] == 'image/gif' ) {
316  if ( $this->getImageArea( $image ) > $wgMaxAnimatedGifArea ) {
317  // Extract initial frame only; we're so big it'll
318  // be a total drag. :P
319  $im->setImageScene( 0 );
320  } elseif ( $this->isAnimatedImage( $image ) ) {
321  // Coalesce is needed to scale animated GIFs properly (T3017).
322  $im = $im->coalesceImages();
323  }
324  // GIF interlacing is only available since 6.3.4
325  if ( $params['interlace'] ) {
326  $im->setInterlaceScheme( Imagick::INTERLACE_GIF );
327  }
328  }
329 
330  $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
331  list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
332 
333  $im->setImageBackgroundColor( new ImagickPixel( 'white' ) );
334 
335  // Call Imagick::thumbnailImage on each frame
336  foreach ( $im as $i => $frame ) {
337  if ( !$frame->thumbnailImage( $width, $height, /* fit */ false ) ) {
338  return $this->getMediaTransformError( $params, "Error scaling frame $i" );
339  }
340  }
341  $im->setImageDepth( 8 );
342 
343  if ( $rotation && !$im->rotateImage( new ImagickPixel( 'white' ), 360 - $rotation ) ) {
344  return $this->getMediaTransformError( $params, "Error rotating $rotation degrees" );
345  }
346 
347  if ( $this->isAnimatedImage( $image ) ) {
348  wfDebug( __METHOD__ . ": Writing animated thumbnail" );
349  // This is broken somehow... can't find out how to fix it
350  $result = $im->writeImages( $params['dstPath'], true );
351  } else {
352  $result = $im->writeImage( $params['dstPath'] );
353  }
354  if ( !$result ) {
355  return $this->getMediaTransformError( $params,
356  "Unable to write thumbnail to {$params['dstPath']}" );
357  }
358  } catch ( ImagickException $e ) {
359  return $this->getMediaTransformError( $params, $e->getMessage() );
360  }
361 
362  return false;
363  }
364 
373  protected function transformCustom( $image, $params ) {
374  # Use a custom convert command
376 
377  # Variables: %s %d %w %h
378  $src = Shell::escape( $params['srcPath'] );
379  $dst = Shell::escape( $params['dstPath'] );
381  $cmd = str_replace( '%s', $src, str_replace( '%d', $dst, $cmd ) ); # Filenames
382  $cmd = str_replace( '%h', Shell::escape( $params['physicalHeight'] ),
383  str_replace( '%w', Shell::escape( $params['physicalWidth'] ), $cmd ) ); # Size
384  wfDebug( __METHOD__ . ": Running custom convert command $cmd" );
385  $retval = 0;
386  $err = wfShellExecWithStderr( $cmd, $retval );
387 
388  if ( $retval !== 0 ) {
389  $this->logErrorForExternalProcess( $retval, $err, $cmd );
390 
391  return $this->getMediaTransformError( $params, $err );
392  }
393 
394  return false; # No error
395  }
396 
405  protected function transformGd( $image, $params ) {
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.
409 
410  $typemap = [
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' ],
417  ];
418 
419  if ( !isset( $typemap[$params['mimeType']] ) ) {
420  $err = 'Image type not supported';
421  wfDebug( $err );
422  $errMsg = wfMessage( 'thumbnail_image-type' )->text();
423 
424  return $this->getMediaTransformError( $params, $errMsg );
425  }
426  list( $loader, $colorStyle, $useQuality, $saveType ) = $typemap[$params['mimeType']];
427 
428  if ( !function_exists( $loader ) ) {
429  $err = "Incomplete GD library configuration: missing function $loader";
430  wfDebug( $err );
431  $errMsg = wfMessage( 'thumbnail_gd-library', $loader )->text();
432 
433  return $this->getMediaTransformError( $params, $errMsg );
434  }
435 
436  if ( !file_exists( $params['srcPath'] ) ) {
437  $err = "File seems to be missing: {$params['srcPath']}";
438  wfDebug( $err );
439  $errMsg = wfMessage( 'thumbnail_image-missing', $params['srcPath'] )->text();
440 
441  return $this->getMediaTransformError( $params, $errMsg );
442  }
443 
444  if ( filesize( $params['srcPath'] ) === 0 ) {
445  $err = "Image file size seems to be zero.";
446  wfDebug( $err );
447  $errMsg = wfMessage( 'thumbnail_image-size-zero', $params['srcPath'] )->text();
448 
449  return $this->getMediaTransformError( $params, $errMsg );
450  }
451 
452  $src_image = $loader( $params['srcPath'] );
453 
454  $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ?
455  $this->getRotation( $image ) :
456  0;
457  list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
458  $dst_image = imagecreatetruecolor( $width, $height );
459 
460  // Initialise the destination image to transparent instead of
461  // the default solid black, to support PNG and GIF transparency nicely
462  $background = imagecolorallocate( $dst_image, 0, 0, 0 );
463  imagecolortransparent( $dst_image, $background );
464  imagealphablending( $dst_image, false );
465 
466  if ( $colorStyle == 'palette' ) {
467  // Don't resample for paletted GIF images.
468  // It may just uglify them, and completely breaks transparency.
469  imagecopyresized( $dst_image, $src_image,
470  0, 0, 0, 0,
471  $width, $height,
472  imagesx( $src_image ), imagesy( $src_image ) );
473  } else {
474  imagecopyresampled( $dst_image, $src_image,
475  0, 0, 0, 0,
476  $width, $height,
477  imagesx( $src_image ), imagesy( $src_image ) );
478  }
479 
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;
484  }
485 
486  imagesavealpha( $dst_image, true );
487 
488  $funcParams = [ $dst_image, $params['dstPath'] ];
489  if ( $useQuality && isset( $params['quality'] ) ) {
490  $funcParams[] = $params['quality'];
491  }
492  $saveType( ...$funcParams );
493 
494  imagedestroy( $dst_image );
495  imagedestroy( $src_image );
496 
497  return false; # No error
498  }
499 
508  public static function imageJpegWrapper( $dst_image, $thumbPath, $quality = null ) {
509  global $wgJpegQuality;
510 
511  if ( $quality === null ) {
512  $quality = $wgJpegQuality;
513  }
514 
515  imageinterlace( $dst_image );
516  imagejpeg( $dst_image, $thumbPath, $quality );
517  }
518 
525  public function canRotate() {
526  $scaler = $this->getScalerType( null, false );
527  switch ( $scaler ) {
528  case 'im':
529  # ImageMagick supports autorotation
530  return true;
531  case 'imext':
532  # Imagick::rotateImage
533  return true;
534  case 'gd':
535  # GD's imagerotate function is used to rotate images, but not
536  # all precompiled PHP versions have that function
537  return function_exists( 'imagerotate' );
538  default:
539  # Other scalers don't support rotation
540  return false;
541  }
542  }
543 
549  public function autoRotateEnabled() {
550  global $wgEnableAutoRotation;
551 
552  if ( $wgEnableAutoRotation === null ) {
553  // Only enable auto-rotation when we actually can
554  return $this->canRotate();
555  }
556 
557  return $wgEnableAutoRotation;
558  }
559 
568  public function rotate( $file, $params ) {
570 
571  $rotation = ( $params['rotation'] + $this->getRotation( $file ) ) % 360;
572  $scene = false;
573 
574  $scaler = $this->getScalerType( null, false );
575  switch ( $scaler ) {
576  case 'im':
577  $cmd = Shell::escape( $wgImageMagickConvertCommand ) . " " .
578  Shell::escape( $this->escapeMagickInput( $params['srcPath'], $scene ) ) .
579  " -rotate " . Shell::escape( "-$rotation" ) . " " .
580  Shell::escape( $this->escapeMagickOutput( $params['dstPath'] ) );
581  wfDebug( __METHOD__ . ": running ImageMagick: $cmd" );
582  $retval = 0;
583  $err = wfShellExecWithStderr( $cmd, $retval );
584  if ( $retval !== 0 ) {
585  $this->logErrorForExternalProcess( $retval, $err, $cmd );
586 
587  return new MediaTransformError( 'thumbnail_error', 0, 0, $err );
588  }
589 
590  return false;
591  case 'imext':
592  $im = new Imagick();
593  $im->readImage( $params['srcPath'] );
594  if ( !$im->rotateImage( new ImagickPixel( 'white' ), 360 - $rotation ) ) {
595  return new MediaTransformError( 'thumbnail_error', 0, 0,
596  "Error rotating $rotation degrees" );
597  }
598  $result = $im->writeImage( $params['dstPath'] );
599  if ( !$result ) {
600  return new MediaTransformError( 'thumbnail_error', 0, 0,
601  "Unable to write image to {$params['dstPath']}" );
602  }
603 
604  return false;
605  default:
606  return new MediaTransformError( 'thumbnail_error', 0, 0,
607  "$scaler rotation not implemented" );
608  }
609  }
610 }
MediaWiki\Shell\Shell
Executes shell commands.
Definition: Shell.php:44
BitmapHandler\parseParamString
parseParamString( $str)
Parse a param string made with makeParamString back into an array.The parameter string without file n...
Definition: BitmapHandler.php:83
MediaTransformError
Basic media transform error class.
Definition: MediaTransformError.php:31
BitmapHandler\validateParam
validateParam( $name, $value)
Validate a thumbnail parameter at parse time.Return true to accept the parameter, and false to reject...
Definition: BitmapHandler.php:97
BitmapHandler\transformImageMagickExt
transformImageMagickExt( $image, $params)
Transform an image using the Imagick PHP extension.
Definition: BitmapHandler.php:283
$wgJpegPixelFormat
$wgJpegPixelFormat
At default setting of 'yuv420', JPEG thumbnails will use 4:2:0 chroma subsampling to reduce file size...
Definition: DefaultSettings.php:1238
TransformationalImageHandler\getMediaTransformError
getMediaTransformError( $params, $errMsg)
Get a MediaTransformError with error 'thumbnail_error'.
Definition: TransformationalImageHandler.php:399
$wgSharpenParameter
$wgSharpenParameter
Sharpening parameter to ImageMagick.
Definition: DefaultSettings.php:1185
BitmapHandler\imageJpegWrapper
static imageJpegWrapper( $dst_image, $thumbPath, $quality=null)
Callback for transformGd when transforming jpeg images.
Definition: BitmapHandler.php:508
TransformationalImageHandler\escapeMagickOutput
escapeMagickOutput( $path, $scene=false)
Escape a string for ImageMagick's output filename.
Definition: TransformationalImageHandler.php:474
BitmapHandler\rotate
rotate( $file, $params)
Stable to override.
Definition: BitmapHandler.php:568
TransformationalImageHandler\escapeMagickProperty
escapeMagickProperty( $s)
Escape a string for ImageMagick's property input (e.g.
Definition: TransformationalImageHandler.php:424
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1220
TransformationalImageHandler
Handler for images that need to be transformed.
Definition: TransformationalImageHandler.php:39
$res
$res
Definition: testCompression.php:57
BitmapHandler\transformCustom
transformCustom( $image, $params)
Transform an image using a custom command.
Definition: BitmapHandler.php:373
MWException
MediaWiki exception.
Definition: MWException.php:29
BitmapHandler
Generic handler for bitmap images.
Definition: BitmapHandler.php:32
$wgUseImageMagick
$wgUseImageMagick
Resizing can be done using PHP's internal image libraries or using ImageMagick or another third-party...
Definition: DefaultSettings.php:1169
TransformationalImageHandler\extractPreRotationDimensions
extractPreRotationDimensions( $params, $rotation)
Extracts the width/height if the image will be scaled before rotating.
Definition: TransformationalImageHandler.php:84
TransformationalImageHandler\escapeMagickInput
escapeMagickInput( $path, $scene=false)
Escape a string for ImageMagick's input filenames.
Definition: TransformationalImageHandler.php:454
$wgMaxInterlacingAreas
$wgMaxInterlacingAreas
Array of max pixel areas for interlacing per MIME type.
Definition: DefaultSettings.php:1180
BitmapHandler\canRotate
canRotate()
Returns whether the current scaler supports rotation (im and gd do) Stable to override.
Definition: BitmapHandler.php:525
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:910
$wgMaxAnimatedGifArea
$wgMaxAnimatedGifArea
Force thumbnailing of animated GIFs above this size to a single frame instead of an animated thumbnai...
Definition: DefaultSettings.php:1335
BitmapHandler\makeParamString
makeParamString( $params)
Merge a parameter array into a string appropriate for inclusion in filenames.Array of parameters that...
Definition: BitmapHandler.php:70
$wgImageMagickConvertCommand
$wgImageMagickConvertCommand
The convert command shipped with ImageMagick.
Definition: DefaultSettings.php:1174
$wgSharpenReductionThreshold
$wgSharpenReductionThreshold
Reduction in linear dimensions below which sharpening will be enabled.
Definition: DefaultSettings.php:1190
BitmapHandler\imageMagickSubsampling
imageMagickSubsampling( $pixelFormat)
Get ImageMagick subsampling factors for the target JPEG pixel format.
Definition: BitmapHandler.php:130
BitmapHandler\transformGd
transformGd( $image, $params)
Transform an image using the built in GD library.
Definition: BitmapHandler.php:405
BitmapHandler\autoRotateEnabled
autoRotateEnabled()
Definition: BitmapHandler.php:549
$wgCustomConvertCommand
$wgCustomConvertCommand
Use another resizing converter, e.g.
Definition: DefaultSettings.php:1210
BitmapHandler\normaliseParams
normaliseParams( $image, &$params)
Stable to override.
Definition: BitmapHandler.php:111
BitmapHandler\transformImageMagick
transformImageMagick( $image, $params)
Transform an image using ImageMagick Stable to override.
Definition: BitmapHandler.php:152
MediaHandler\logErrorForExternalProcess
logErrorForExternalProcess( $retval, $err, $cmd)
Log an error that occurred in an external process.
Definition: MediaHandler.php:821
MediaHandler\isAnimatedImage
isAnimatedImage( $file)
The material is an image, and is animated.
Definition: MediaHandler.php:402
$wgJpegQuality
$wgJpegQuality
When scaling a JPEG thumbnail, this is the quality we request from the backend.
Definition: DefaultSettings.php:1247
BitmapHandler\getScalerType
getScalerType( $dstPath, $checkDstPath=true)
Returns which scaler type should be used.
Definition: BitmapHandler.php:43
$wgUseImageResize
$wgUseImageResize
Whether to enable server-side image thumbnailing.
Definition: DefaultSettings.php:1159
ImageHandler\getImageArea
getImageArea( $image)
Function that returns the number of pixels to be thumbnailed.
Definition: ImageHandler.php:254
MediaHandler\getRotation
getRotation( $file)
On supporting image formats, try to read out the low-level orientation of the file and return the ang...
Definition: MediaHandler.php:806
$wgEnableAutoRotation
$wgEnableAutoRotation
If set to true, images that contain certain the exif orientation tag will be rotated accordingly.
Definition: DefaultSettings.php:1413
wfShellExecWithStderr
wfShellExecWithStderr( $cmd, &$retval=null, $environ=[], $limits=[])
Execute a shell command, returning both stdout and stderr.
Definition: GlobalFunctions.php:2112
$wgImageMagickTempDir
$wgImageMagickTempDir
Temporary directory used for ImageMagick.
Definition: DefaultSettings.php:1196