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  if ( version_compare( $this->getMagickVersion(), "6.5.6" ) >= 0 ) {
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  // We optimize the output, but -optimize is broken,
203  // use optimizeTransparency instead (T13822)
204  if ( version_compare( $this->getMagickVersion(), "6.3.5" ) >= 0 ) {
205  $animation_post = [ '-fuzz', '5%', '-layers', 'optimizeTransparency' ];
206  }
207  }
208  if ( $params['interlace'] && version_compare( $this->getMagickVersion(), "6.3.4" ) >= 0
209  && !$this->isAnimatedImage( $image ) ) { // 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  Wikimedia\suppressWarnings();
226  $xcfMeta = unserialize( $image->getMetadata() );
227  Wikimedia\restoreWarnings();
228  if ( $xcfMeta
229  && isset( $xcfMeta['colorType'] )
230  && $xcfMeta['colorType'] === 'greyscale-alpha'
231  && version_compare( $this->getMagickVersion(), "6.8.9-3" ) < 0
232  ) {
233  // T68323 - Greyscale images not rendered properly.
234  // So only take the "red" channel.
235  $channelOnly = [ '-channel', 'R', '-separate' ];
236  $animation_pre = array_merge( $animation_pre, $channelOnly );
237  }
238  }
239 
240  // Use one thread only, to avoid deadlock bugs on OOM
241  $env = [ 'OMP_NUM_THREADS' => 1 ];
242  if ( strval( $wgImageMagickTempDir ) !== '' ) {
243  $env['MAGICK_TMPDIR'] = $wgImageMagickTempDir;
244  }
245 
246  $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
247  list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
248 
249  $cmd = Shell::escape( ...array_merge(
251  $quality,
252  // Specify white background color, will be used for transparent images
253  // in Internet Explorer/Windows instead of default black.
254  [ '-background', 'white' ],
255  $decoderHint,
256  [ $this->escapeMagickInput( $params['srcPath'], $scene ) ],
257  $animation_pre,
258  // For the -thumbnail option a "!" is needed to force exact size,
259  // or ImageMagick may decide your ratio is wrong and slice off
260  // a pixel.
261  [ '-thumbnail', "{$width}x{$height}!" ],
262  // Add the source url as a comment to the thumb, but don't add the flag if there's no comment
263  ( $params['comment'] !== ''
264  ? [ '-set', 'comment', $this->escapeMagickProperty( $params['comment'] ) ]
265  : [] ),
266  // T108616: Avoid exposure of local file path
267  [ '+set', 'Thumb::URI' ],
268  [ '-depth', 8 ],
269  $sharpen,
270  [ '-rotate', "-$rotation" ],
271  $subsampling,
272  $animation_post,
273  [ $this->escapeMagickOutput( $params['dstPath'] ) ] ) );
274 
275  wfDebug( __METHOD__ . ": running ImageMagick: $cmd" );
276  $retval = 0;
277  $err = wfShellExecWithStderr( $cmd, $retval, $env );
278 
279  if ( $retval !== 0 ) {
280  $this->logErrorForExternalProcess( $retval, $err, $cmd );
281 
282  return $this->getMediaTransformError( $params, "$err\nError code: $retval" );
283  }
284 
285  return false; # No error
286  }
287 
296  protected function transformImageMagickExt( $image, $params ) {
299 
300  try {
301  $im = new Imagick();
302  $im->readImage( $params['srcPath'] );
303 
304  if ( $params['mimeType'] == 'image/jpeg' ) {
305  // Sharpening, see T8193
306  if ( ( $params['physicalWidth'] + $params['physicalHeight'] )
307  / ( $params['srcWidth'] + $params['srcHeight'] )
309  ) {
310  // Hack, since $wgSharpenParameter is written specifically for the command line convert
311  list( $radius, $sigma ) = explode( 'x', $wgSharpenParameter );
312  $im->sharpenImage( $radius, $sigma );
313  }
314  $qualityVal = isset( $params['quality'] ) ? (string)$params['quality'] : null;
315  $im->setCompressionQuality( $qualityVal ?: $wgJpegQuality );
316  if ( $params['interlace'] ) {
317  $im->setInterlaceScheme( Imagick::INTERLACE_JPEG );
318  }
319  if ( $wgJpegPixelFormat ) {
320  $factors = $this->imageMagickSubsampling( $wgJpegPixelFormat );
321  $im->setSamplingFactors( $factors );
322  }
323  } elseif ( $params['mimeType'] == 'image/png' ) {
324  $im->setCompressionQuality( 95 );
325  if ( $params['interlace'] ) {
326  $im->setInterlaceScheme( Imagick::INTERLACE_PNG );
327  }
328  } elseif ( $params['mimeType'] == 'image/gif' ) {
329  if ( $this->getImageArea( $image ) > $wgMaxAnimatedGifArea ) {
330  // Extract initial frame only; we're so big it'll
331  // be a total drag. :P
332  $im->setImageScene( 0 );
333  } elseif ( $this->isAnimatedImage( $image ) ) {
334  // Coalesce is needed to scale animated GIFs properly (T3017).
335  $im = $im->coalesceImages();
336  }
337  // GIF interlacing is only available since 6.3.4
338  $v = Imagick::getVersion();
339  preg_match( '/ImageMagick ([0-9]+\.[0-9]+\.[0-9]+)/', $v['versionString'], $v );
340 
341  if ( $params['interlace'] && version_compare( $v[1], '6.3.4' ) >= 0 ) {
342  $im->setInterlaceScheme( Imagick::INTERLACE_GIF );
343  }
344  }
345 
346  $rotation = isset( $params['disableRotation'] ) ? 0 : $this->getRotation( $image );
347  list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
348 
349  $im->setImageBackgroundColor( new ImagickPixel( 'white' ) );
350 
351  // Call Imagick::thumbnailImage on each frame
352  foreach ( $im as $i => $frame ) {
353  if ( !$frame->thumbnailImage( $width, $height, /* fit */ false ) ) {
354  return $this->getMediaTransformError( $params, "Error scaling frame $i" );
355  }
356  }
357  $im->setImageDepth( 8 );
358 
359  if ( $rotation && !$im->rotateImage( new ImagickPixel( 'white' ), 360 - $rotation ) ) {
360  return $this->getMediaTransformError( $params, "Error rotating $rotation degrees" );
361  }
362 
363  if ( $this->isAnimatedImage( $image ) ) {
364  wfDebug( __METHOD__ . ": Writing animated thumbnail" );
365  // This is broken somehow... can't find out how to fix it
366  $result = $im->writeImages( $params['dstPath'], true );
367  } else {
368  $result = $im->writeImage( $params['dstPath'] );
369  }
370  if ( !$result ) {
371  return $this->getMediaTransformError( $params,
372  "Unable to write thumbnail to {$params['dstPath']}" );
373  }
374  } catch ( ImagickException $e ) {
375  return $this->getMediaTransformError( $params, $e->getMessage() );
376  }
377 
378  return false;
379  }
380 
389  protected function transformCustom( $image, $params ) {
390  # Use a custom convert command
392 
393  # Variables: %s %d %w %h
394  $src = Shell::escape( $params['srcPath'] );
395  $dst = Shell::escape( $params['dstPath'] );
397  $cmd = str_replace( '%s', $src, str_replace( '%d', $dst, $cmd ) ); # Filenames
398  $cmd = str_replace( '%h', Shell::escape( $params['physicalHeight'] ),
399  str_replace( '%w', Shell::escape( $params['physicalWidth'] ), $cmd ) ); # Size
400  wfDebug( __METHOD__ . ": Running custom convert command $cmd" );
401  $retval = 0;
402  $err = wfShellExecWithStderr( $cmd, $retval );
403 
404  if ( $retval !== 0 ) {
405  $this->logErrorForExternalProcess( $retval, $err, $cmd );
406 
407  return $this->getMediaTransformError( $params, $err );
408  }
409 
410  return false; # No error
411  }
412 
421  protected function transformGd( $image, $params ) {
422  # Use PHP's builtin GD library functions.
423  # First find out what kind of file this is, and select the correct
424  # input routine for this.
425 
426  $typemap = [
427  'image/gif' => [ 'imagecreatefromgif', 'palette', false, 'imagegif' ],
428  'image/jpeg' => [ 'imagecreatefromjpeg', 'truecolor', true,
429  [ __CLASS__, 'imageJpegWrapper' ] ],
430  'image/png' => [ 'imagecreatefrompng', 'bits', false, 'imagepng' ],
431  'image/vnd.wap.wbmp' => [ 'imagecreatefromwbmp', 'palette', false, 'imagewbmp' ],
432  'image/xbm' => [ 'imagecreatefromxbm', 'palette', false, 'imagexbm' ],
433  ];
434 
435  if ( !isset( $typemap[$params['mimeType']] ) ) {
436  $err = 'Image type not supported';
437  wfDebug( $err );
438  $errMsg = wfMessage( 'thumbnail_image-type' )->text();
439 
440  return $this->getMediaTransformError( $params, $errMsg );
441  }
442  list( $loader, $colorStyle, $useQuality, $saveType ) = $typemap[$params['mimeType']];
443 
444  if ( !function_exists( $loader ) ) {
445  $err = "Incomplete GD library configuration: missing function $loader";
446  wfDebug( $err );
447  $errMsg = wfMessage( 'thumbnail_gd-library', $loader )->text();
448 
449  return $this->getMediaTransformError( $params, $errMsg );
450  }
451 
452  if ( !file_exists( $params['srcPath'] ) ) {
453  $err = "File seems to be missing: {$params['srcPath']}";
454  wfDebug( $err );
455  $errMsg = wfMessage( 'thumbnail_image-missing', $params['srcPath'] )->text();
456 
457  return $this->getMediaTransformError( $params, $errMsg );
458  }
459 
460  if ( filesize( $params['srcPath'] ) === 0 ) {
461  $err = "Image file size seems to be zero.";
462  wfDebug( $err );
463  $errMsg = wfMessage( 'thumbnail_image-size-zero', $params['srcPath'] )->text();
464 
465  return $this->getMediaTransformError( $params, $errMsg );
466  }
467 
468  $src_image = $loader( $params['srcPath'] );
469 
470  $rotation = function_exists( 'imagerotate' ) && !isset( $params['disableRotation'] ) ?
471  $this->getRotation( $image ) :
472  0;
473  list( $width, $height ) = $this->extractPreRotationDimensions( $params, $rotation );
474  $dst_image = imagecreatetruecolor( $width, $height );
475 
476  // Initialise the destination image to transparent instead of
477  // the default solid black, to support PNG and GIF transparency nicely
478  $background = imagecolorallocate( $dst_image, 0, 0, 0 );
479  imagecolortransparent( $dst_image, $background );
480  imagealphablending( $dst_image, false );
481 
482  if ( $colorStyle == 'palette' ) {
483  // Don't resample for paletted GIF images.
484  // It may just uglify them, and completely breaks transparency.
485  imagecopyresized( $dst_image, $src_image,
486  0, 0, 0, 0,
487  $width, $height,
488  imagesx( $src_image ), imagesy( $src_image ) );
489  } else {
490  imagecopyresampled( $dst_image, $src_image,
491  0, 0, 0, 0,
492  $width, $height,
493  imagesx( $src_image ), imagesy( $src_image ) );
494  }
495 
496  if ( $rotation % 360 != 0 && $rotation % 90 == 0 ) {
497  $rot_image = imagerotate( $dst_image, $rotation, 0 );
498  imagedestroy( $dst_image );
499  $dst_image = $rot_image;
500  }
501 
502  imagesavealpha( $dst_image, true );
503 
504  $funcParams = [ $dst_image, $params['dstPath'] ];
505  if ( $useQuality && isset( $params['quality'] ) ) {
506  $funcParams[] = $params['quality'];
507  }
508  $saveType( ...$funcParams );
509 
510  imagedestroy( $dst_image );
511  imagedestroy( $src_image );
512 
513  return false; # No error
514  }
515 
524  public static function imageJpegWrapper( $dst_image, $thumbPath, $quality = null ) {
525  global $wgJpegQuality;
526 
527  if ( $quality === null ) {
528  $quality = $wgJpegQuality;
529  }
530 
531  imageinterlace( $dst_image );
532  imagejpeg( $dst_image, $thumbPath, $quality );
533  }
534 
541  public function canRotate() {
542  $scaler = $this->getScalerType( null, false );
543  switch ( $scaler ) {
544  case 'im':
545  # ImageMagick supports autorotation
546  return true;
547  case 'imext':
548  # Imagick::rotateImage
549  return true;
550  case 'gd':
551  # GD's imagerotate function is used to rotate images, but not
552  # all precompiled PHP versions have that function
553  return function_exists( 'imagerotate' );
554  default:
555  # Other scalers don't support rotation
556  return false;
557  }
558  }
559 
565  public function autoRotateEnabled() {
566  global $wgEnableAutoRotation;
567 
568  if ( $wgEnableAutoRotation === null ) {
569  // Only enable auto-rotation when we actually can
570  return $this->canRotate();
571  }
572 
573  return $wgEnableAutoRotation;
574  }
575 
584  public function rotate( $file, $params ) {
586 
587  $rotation = ( $params['rotation'] + $this->getRotation( $file ) ) % 360;
588  $scene = false;
589 
590  $scaler = $this->getScalerType( null, false );
591  switch ( $scaler ) {
592  case 'im':
593  $cmd = Shell::escape( $wgImageMagickConvertCommand ) . " " .
594  Shell::escape( $this->escapeMagickInput( $params['srcPath'], $scene ) ) .
595  " -rotate " . Shell::escape( "-$rotation" ) . " " .
596  Shell::escape( $this->escapeMagickOutput( $params['dstPath'] ) );
597  wfDebug( __METHOD__ . ": running ImageMagick: $cmd" );
598  $retval = 0;
599  $err = wfShellExecWithStderr( $cmd, $retval );
600  if ( $retval !== 0 ) {
601  $this->logErrorForExternalProcess( $retval, $err, $cmd );
602 
603  return new MediaTransformError( 'thumbnail_error', 0, 0, $err );
604  }
605 
606  return false;
607  case 'imext':
608  $im = new Imagick();
609  $im->readImage( $params['srcPath'] );
610  if ( !$im->rotateImage( new ImagickPixel( 'white' ), 360 - $rotation ) ) {
611  return new MediaTransformError( 'thumbnail_error', 0, 0,
612  "Error rotating $rotation degrees" );
613  }
614  $result = $im->writeImage( $params['dstPath'] );
615  if ( !$result ) {
616  return new MediaTransformError( 'thumbnail_error', 0, 0,
617  "Unable to write image to {$params['dstPath']}" );
618  }
619 
620  return false;
621  default:
622  return new MediaTransformError( 'thumbnail_error', 0, 0,
623  "$scaler rotation not implemented" );
624  }
625  }
626 }
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:296
$wgJpegPixelFormat
$wgJpegPixelFormat
At default setting of 'yuv420', JPEG thumbnails will use 4:2:0 chroma subsampling to reduce file size...
Definition: DefaultSettings.php:1247
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:1194
BitmapHandler\imageJpegWrapper
static imageJpegWrapper( $dst_image, $thumbPath, $quality=null)
Callback for transformGd when transforming jpeg images.
Definition: BitmapHandler.php:524
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:584
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:1219
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:389
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:1178
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:1189
BitmapHandler\canRotate
canRotate()
Returns whether the current scaler supports rotation (im and gd do) Stable to override.
Definition: BitmapHandler.php:541
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:909
$wgMaxAnimatedGifArea
$wgMaxAnimatedGifArea
Force thumbnailing of animated GIFs above this size to a single frame instead of an animated thumbnai...
Definition: DefaultSettings.php:1344
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:1183
$wgSharpenReductionThreshold
$wgSharpenReductionThreshold
Reduction in linear dimensions below which sharpening will be enabled.
Definition: DefaultSettings.php:1199
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:421
TransformationalImageHandler\getMagickVersion
getMagickVersion()
Retrieve the version of the installed ImageMagick You can use PHPs version_compare() to use this valu...
Definition: TransformationalImageHandler.php:520
BitmapHandler\autoRotateEnabled
autoRotateEnabled()
Definition: BitmapHandler.php:565
$wgCustomConvertCommand
$wgCustomConvertCommand
Use another resizing converter, e.g.
Definition: DefaultSettings.php:1219
unserialize
unserialize( $serialized)
Definition: ApiMessageTrait.php:146
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:1256
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:1168
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:1422
wfShellExecWithStderr
wfShellExecWithStderr( $cmd, &$retval=null, $environ=[], $limits=[])
Execute a shell command, returning both stdout and stderr.
Definition: GlobalFunctions.php:2105
$wgImageMagickTempDir
$wgImageMagickTempDir
Temporary directory used for ImageMagick.
Definition: DefaultSettings.php:1205