Diff
checker
Text
Text
Bilder
Dokumente
Excel
Ordner
Legal
Enterprise
Desktop-App
Preise
Einloggen
Diffchecker Desktop herunterladen
Texte vergleichen
Finde den Unterschied zwischen zwei Textdateien
Werkzeuge
Verlauf
Live-Editor
Gleiches ausblenden
Zeilenumbruch aus
Ansicht
Zweispaltig
Einspaltig
Vergleichsgenauigkeit
Intelligent
Wort
Zeichen
Syntaxhervorhebung
Syntax auswählen
Ignorieren
Text umwandeln
Zur ersten Änderung
Eingabe bearbeiten
Diffchecker Desktop
Der sicherste Weg, Diffchecker zu nutzen. Hol dir die Desktop-App: Deine Diffs verlassen nie deinen Computer!
Desktop holen
Imagemagick.php
Erstellt
vor 10 Monaten
Diff läuft nie ab
Löschen
Exportieren
Teilen
Erklären
33 Entfernungen
Zeilen
Gesamt
Entfernt
Zeichen
Gesamt
Entfernt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
397 Zeilen
Kopieren
88 Hinzufügungen
Zeilen
Gesamt
Hinzugefügt
Zeichen
Gesamt
Hinzugefügt
Um diese Funktion weiterhin zu nutzen, aktualisiere auf
Diff
checker
Pro
Preise anzeigen
451 Zeilen
Kopieren
<?php
<?php
/**
/**
* @brief Image Class - ImageMagick
* @brief Image Class - ImageMagick
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @package Invision Community
* @since 06 Mar 2014
* @since 06 Mar 2014
*/
*/
namespace IPS\Image;
namespace IPS\Image;
/* To prevent PHP errors (extending class does not exist) revealing path */
/* To prevent PHP errors (extending class does not exist) revealing path */
use Imagick;
use Imagick;
use ImagickDraw;
use ImagickDraw;
use ImagickException;
use ImagickException;
use ImagickPixel;
use ImagickPixel;
use InvalidArgumentException;
use InvalidArgumentException;
use IPS\Image;
use IPS\Image;
use IPS\Settings;
use IPS\Settings;
use function count;
use function count;
use function defined;
use function defined;
use function file_put_contents;
use function file_put_contents;
use function in_array;
use function in_array;
use const IPS\TEMP_DIRECTORY;
use const IPS\TEMP_DIRECTORY;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
exit;
}
}
/**
/**
* Image Class - ImageMagick
* Image Class - ImageMagick
*/
*/
class Imagemagick extends Image
class Imagemagick extends Image
{
{
/**
/**
* @brief Temporary filename
* @brief Temporary filename
*/
*/
protected string|null|false $tempFile = NULL;
protected string|null|false $tempFile = NULL;
/**
/**
* @brief Imagick object
* @brief Imagick object
*/
*/
protected Imagick $imagick;
protected Imagick $imagick;
/**
/**
* Constructor
* Constructor
*
*
* @param string|null $contents Contents
* @param string|null $contents Contents
* @param bool $noImage We are creating a new instance of the object internally and are not passing an image string
* @param bool $noImage We are creating a new instance of the object internally and are not passing an image string
* @return void
* @return void
* @throws InvalidArgumentException
* @throws InvalidArgumentException
*/
*/
public function __construct( ?string $contents, bool $noImage=FALSE )
public function __construct( ?string $contents, bool $noImage=FALSE )
{
{
/* If we are just creating an instance of the object without passing image contents as a string, return now */
/* If we are just creating an instance of the object without passing image contents as a string, return now */
if( $noImage === TRUE )
if( $noImage === TRUE )
{
{
return;
return;
}
}
$this->tempFile = tempnam( TEMP_DIRECTORY, 'imagick' );
$this->tempFile = tempnam( TEMP_DIRECTORY, 'imagick' );
Kopieren
Kopiert
Kopieren
Kopiert
if ( $this->tempFile === FALSE )
{
throw new \RuntimeException('Unable to create temporary file for ImageMagick');
}
file_put_contents( $this->tempFile, $contents );
file_put_contents( $this->tempFile, $contents );
try
try
{
{
$this->imagick = new Imagick( $this->tempFile );
$this->imagick = new Imagick( $this->tempFile );
Kopieren
Kopiert
Kopieren
Kopiert
/* Set quality (if image format is JPEG
) */
/* Set quality (if image format is JPEG
, WEBP, or AVIF
) */
if ( in_array( mb_strtolower( $this->imagick->getImageFormat() ), array( 'jpg', 'jpeg', 'webp', 'avif' ) ) )
if ( in_array( mb_strtolower( $this->imagick->getImageFormat() ), array( 'jpg', 'jpeg', 'webp', 'avif' ) ) )
{
{
$this->imagick->setImageCompressionQuality( (int) Settings::i()->image_jpg_quality ?: 85 );
$this->imagick->setImageCompressionQuality( (int) Settings::i()->image_jpg_quality ?: 85 );
}
}
}
}
catch ( ImagickException $e )
catch ( ImagickException $e )
{
{
Kopieren
Kopiert
Kopieren
Kopiert
if ( $this->tempFile !== NULL && @is_file( $this->tempFile ) )
{
@unlink( $this->tempFile );
}
throw new InvalidArgumentException( $e->getMessage(), $e->getCode() );
throw new InvalidArgumentException( $e->getMessage(), $e->getCode() );
}
}
/* Set width/height */
/* Set width/height */
$this->setDimensions();
$this->setDimensions();
}
}
/**
/**
* Destructor
* Destructor
*
*
* @return void
* @return void
*/
*/
public function __destruct()
public function __destruct()
{
{
Kopieren
Kopiert
Kopieren
Kopiert
if( $this->tempFile !== NULL
)
if( $this->tempFile !== NULL
&& @is_file( $this->tempFile )
)
{
{
Kopieren
Kopiert
Kopieren
Kopiert
unlink( $this->tempFile );
@
unlink( $this->tempFile );
}
}
}
}
/**
/**
* Get Contents
* Get Contents
*
*
* @return string
* @return string
*/
*/
public function __toString()
public function __toString()
{
{
/* If possible, retain the color profiles when stripping EXIF data */
/* If possible, retain the color profiles when stripping EXIF data */
if( Settings::i()->imagick_strip_exif )
if( Settings::i()->imagick_strip_exif )
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$imageColorProfiles
= array();
$imageColorProfiles
= array();
try
try
{
{
$imageColorProfiles = $this->imagick->getImageProfiles( 'icc' );
$imageColorProfiles = $this->imagick->getImageProfiles( 'icc' );
}
}
catch( ImagickException $e ){}
catch( ImagickException $e ){}
$this->imagick->stripImage();
$this->imagick->stripImage();
if( count( $imageColorProfiles ) )
if( count( $imageColorProfiles ) )
{
{
foreach( $imageColorProfiles as $type => $profile )
foreach( $imageColorProfiles as $type => $profile )
{
{
try
try
{
{
$this->imagick->profileImage( $type, $profile );
$this->imagick->profileImage( $type, $profile );
}
}
catch( ImagickException $e ){}
catch( ImagickException $e ){}
}
}
}
}
}
}
return $this->imagick->getImagesBlob();
return $this->imagick->getImagesBlob();
}
}
/**
/**
Kopieren
Kopiert
Kopieren
Kopiert
* Automatically orient the image based on EXIF data
*
* @return void
*/
public function autoOrient(): void
{
try
{
$this->imagick->autoOrient();
$this->setDimensions();
error_log("Après autoOrient - Largeur: {$this->width}, Hauteur: {$this->height}");
}
catch ( ImagickException $e )
{
error_log("Erreur autoOrient: " . $e->getMessage());
}
}
/**
* Resize
* Resize
*
*
Kopieren
Kopiert
Kopieren
Kopiert
* @param int $width
Width (in pixels)
* @param int $width
Width (in pixels)
* @param int $height
Height (in pixels)
* @param int $height
Height (in pixels)
* @return void
* @return void
*/
*/
public function resize( int $width, int $height ) : void
public function resize( int $width, int $height ) : void
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$format =
$this->imagick->getImageFormat()
;
$format =
mb_strtolower(
$this->imagick->getImageFormat()
)
;
Kopieren
Kopiert
Kopieren
Kopiert
if(
mb_strtolower(
$format
)
== 'gif' )
if(
$format
== 'gif' )
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$this->imagick
= $this->imagick->coalesceImages();
$this->imagick
= $this->imagick->coalesceImages();
foreach( $this->imagick as $frame )
foreach( $this->imagick as $frame )
{
{
$frame->thumbnailImage( $width, $height );
$frame->thumbnailImage( $width, $height );
}
}
/* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */
/* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */
try
try
{
{
$this->imagick->optimizeImageLayers();
$this->imagick->optimizeImageLayers();
}
}
catch( ImagickException $e )
catch( ImagickException $e )
{
{
$this->imagick->deconstructImages();
$this->imagick->deconstructImages();
}
}
}
}
else
else
{
{
$this->imagick->thumbnailImage( $width, $height );
$this->imagick->thumbnailImage( $width, $height );
}
}
/* Set width/height */
/* Set width/height */
$this->setDimensions();
$this->setDimensions();
}
}
/**
/**
Kopieren
Kopiert
Kopieren
Kopiert
* Crop to a given width and height
(will attempt to downsize first)
* Crop to a given width and height
*
*
Kopieren
Kopiert
Kopieren
Kopiert
* @param int $width
Width (in pixels)
* @param int $width
Width (in pixels)
* @param int $height
Height (in pixels)
* @param int $height
Height (in pixels)
* @return void
* @return void
*/
*/
public function crop( int $width, int $height ) : void
public function crop( int $width, int $height ) : void
{
{
$this->imagick->cropThumbnailImage( $width, $height );
$this->imagick->cropThumbnailImage( $width, $height );
/* Set width/height */
/* Set width/height */
$this->setDimensions();
$this->setDimensions();
}
}
/**
/**
* Crop at specific points
* Crop at specific points
*
*
Kopieren
Kopiert
Kopieren
Kopiert
* @param int $point1X
x-point for top-left corner
* @param int $point1X
x-point for top-left corner
* @param int $point1Y
y-point for top-left corner
* @param int $point1Y
y-point for top-left corner
* @param int $point2X
x-point for bottom-right corner
* @param int $point2X
x-point for bottom-right corner
* @param int $point2Y
y-point for bottom-right corner
* @param int $point2Y
y-point for bottom-right corner
* @return void
* @return void
*/
*/
public function cropToPoints( int $point1X, int $point1Y, int $point2X, int $point2Y ) : void
public function cropToPoints( int $point1X, int $point1Y, int $point2X, int $point2Y ) : void
{
{
Kopieren
Kopiert
Kopieren
Kopiert
if(
mb_strtolower( $this->imagick->getImageFormat() )
=== 'gif' )
$format =
mb_strtolower( $this->imagick->getImageFormat() )
;
if( $format
=== 'gif' )
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$this->imagick
= $this->imagick->coalesceImages();
$this->imagick
= $this->imagick->coalesceImages();
foreach( $this->imagick as $frame )
foreach( $this->imagick as $frame )
{
{
$frame->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y );
$frame->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y );
Kopieren
Kopiert
Kopieren
Kopiert
$frame->setImagePage(
$point2X - $point1X, $point2Y - $point1Y, 0, 0
);
$frame->setImagePage(
$point2X - $point1X, $point2Y - $point1Y, 0, 0
);
}
}
/* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */
/* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */
try
try
{
{
$this->imagick->optimizeImageLayers();
$this->imagick->optimizeImageLayers();
}
}
catch( ImagickException $e )
catch( ImagickException $e )
{
{
$this->imagick->deconstructImages();
$this->imagick->deconstructImages();
}
}
}
}
else
else
{
{
$this->imagick->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y );
$this->imagick->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y );
}
}
/* Set width/height */
/* Set width/height */
$this->setDimensions();
$this->setDimensions();
}
}
/**
/**
* Impose image
* Impose image
*
*
* @param Image $image Image to impose
* @param Image $image Image to impose
* @param int $x Location to impose to, x axis
* @param int $x Location to impose to, x axis
* @param int $y Location to impose to, y axis
* @param int $y Location to impose to, y axis
* @return void
* @return void
*/
*/
public function impose( Image $image, int $x=0, int $y=0 ) : void
public function impose( Image $image, int $x=0, int $y=0 ) : void
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$this->imagick->compositeImage( $image->imagick, Imagick::COMPOSITE_DEFAULT, $x, $y );
if ( $image instanceof Imagemagick )
{
$this->imagick->compositeImage( $image->imagick, Imagick::COMPOSITE_DEFAULT, $x, $y );
}
}
}
/**
/**
* Rotate image
* Rotate image
*
*
* @param int $angle Angle of rotation
* @param int $angle Angle of rotation
* @return void
* @return void
*/
*/
public function rotate( int $angle ) : void
public function rotate( int $angle ) : void
{
{
$this->imagick->rotateImage( new ImagickPixel('#00000000'), $angle );
$this->imagick->rotateImage( new ImagickPixel('#00000000'), $angle );
/* Set width/height */
/* Set width/height */
$this->setDimensions();
$this->setDimensions();
}
}
/**
/**
Kopieren
Kopiert
Kopieren
Kopiert
* Flip image horizontally
*
* @return void
* @return void
*/
*/
public function flip(): void
public function flip(): void
{
{
$this->imagick->flopImage();
$this->imagick->flopImage();
/* Set width/height */
/* Set width/height */
$this->setDimensions();
$this->setDimensions();
}
}
/**
/**
* Set the image width and height
* Set the image width and height
*
*
* @return void
* @return void
*/
*/
protected function setDimensions() : void
protected function setDimensions() : void
{
{
/* If this is a gif, we need to coalesce the image in order to get the proper dimensions */
/* If this is a gif, we need to coalesce the image in order to get the proper dimensions */
if ( mb_strtolower( $this->imagick->getImageFormat() ) === 'gif' )
if ( mb_strtolower( $this->imagick->getImageFormat() ) === 'gif' )
{
{
$this->imagick = $this->imagick->coalesceImages();
$this->imagick = $this->imagick->coalesceImages();
}
}
/* Set width/height */
/* Set width/height */
$this->width = $this->imagick->getImageWidth();
$this->width = $this->imagick->getImageWidth();
$this->height = $this->imagick->getImageHeight();
$this->height = $this->imagick->getImageHeight();
}
}
/**
/**
* Get Image Orientation
* Get Image Orientation
*
*
Kopieren
Kopiert
Kopieren
Kopiert
* @return int|
NULL
* @return int|
null
*/
*/
Kopieren
Kopiert
Kopieren
Kopiert
public function getImageOrientation():
int
|NULL
public function getImageOrientation():
?
int
{
{
try
try
{
{
if ( $orientation = parent::getImageOrientation() )
if ( $orientation = parent::getImageOrientation() )
{
{
return $orientation;
return $orientation;
}
}
/* This method does not exist in ImageMagick < 6.6.4 */
/* This method does not exist in ImageMagick < 6.6.4 */
Kopieren
Kopiert
Kopieren
Kopiert
return ( method_exists( $this->imagick, 'getImageOrientation' ) ) ? $this->imagick->getImageOrientation() :
NULL
;
return ( method_exists( $this->imagick, 'getImageOrientation' ) ) ? $this->imagick->getImageOrientation() :
null
;
}
}
catch( ImagickException $e )
catch( ImagickException $e )
{
{
Kopieren
Kopiert
Kopieren
Kopiert
return
NULL
;
return
null
;
}
}
}
}
/**
/**
* Set image orientation
* Set image orientation
*
*
* @param int $orientation The orientation
* @param int $orientation The orientation
* @return void
* @return void
*/
*/
public function setImageOrientation( int $orientation ) : void
public function setImageOrientation( int $orientation ) : void
{
{
Kopieren
Kopiert
Kopieren
Kopiert
if( method_exists( $this->imagick, '
g
etImageOrientation' ) )
if( method_exists( $this->imagick, '
s
etImageOrientation' ) )
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$this->imagick->setImageOrientation(
$orientation
);
$this->imagick->setImageOrientation(
$orientation
);
}
}
}
}
/**
/**
Kopieren
Kopiert
Kopieren
Kopiert
* Get Image Width
*
* @return int|null
*/
public function getWidth(): ?int
{
return $this->imagick->getImageWidth();
}
/**
* Get Image Height
*
* @return int|null
*/
public function getHeight(): ?int
{
return $this->imagick->getImageHeight();
}
/**
* Can we write text reliably on an image?
* Can we write text reliably on an image?
*
*
* @return bool
* @return bool
*/
*/
public static function canWriteText(): bool
public static function canWriteText(): bool
{
{
Kopieren
Kopiert
Kopieren
Kopiert
return
TRUE
;
return
true
;
}
}
/**
/**
* Create a new blank canvas image
* Create a new blank canvas image
*
*
* @param int $width Width
* @param int $width Width
* @param int $height Height
* @param int $height Height
* @param array $rgb Color to use for bg
* @param array $rgb Color to use for bg
* @return Image
* @return Image
*/
*/
public static function newImageCanvas( int $width, int $height, array $rgb ): Image
public static function newImageCanvas( int $width, int $height, array $rgb ): Image
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$obj
= new static(
NULL, TRUE
);
$obj
= new static(
null, true
);
$obj->imagick
= new Imagick();
$obj->imagick
= new Imagick();
$obj->width
= $width;
$obj->width
= $width;
$obj->height
= $height;
$obj->height
= $height;
$obj->type
= 'png';
$obj->type
= 'png';
$pixel
= new ImagickPixel( "rgba({$rgb[0]}, {$rgb[1]}, {$rgb[2]}, 1)" );
$pixel
= new ImagickPixel( "rgba({$rgb[0]}, {$rgb[1]}, {$rgb[2]}, 1)" );
$obj->imagick->newImage( $width, $height, $pixel );
$obj->imagick->newImage( $width, $height, $pixel );
Kopieren
Kopiert
Kopieren
Kopiert
$obj->imagick->setImageFormat(
"
png
"
);
$obj->imagick->setImageFormat(
'
png
'
);
return $obj;
return $obj;
}
}
/**
/**
* Write text on our image
* Write text on our image
*
*
* @param string $text Text
* @param string $text Text
* @param string $font Path to font to use
* @param string $font Path to font to use
* @param int $size Size of text
* @param int $size Size of text
* @return void
* @return void
*/
*/
public function write( string $text, string $font, int $size ) : void
public function write( string $text, string $font, int $size ) : void
{
{
Kopieren
Kopiert
Kopieren
Kopiert
$draw
= new ImagickDraw();
$draw
= new ImagickDraw();
$draw->setTextAntialias( true );
$draw->setTextAntialias( true );
$draw->setGravity( Imagick::GRAVITY_CENTER );
$draw->setGravity( Imagick::GRAVITY_CENTER );
$draw->setFont( $font );
$draw->setFont( $font );
$draw->setFontSize( $size );
$draw->setFontSize( $size );
Kopieren
Kopiert
Kopieren
Kopiert
$draw->setFillColor( new ImagickPixel(
"
rgba(255,255,255,1)
"
) );
$draw->setFillColor( new ImagickPixel(
'
rgba(255,255,255,1)
'
) );
$this->imagick->annotateImage( $draw, 0, 0, 0, $text );
$this->imagick->annotateImage( $draw, 0, 0, 0, $text );
}
}
/**
/**
* Return an array of supported extensions
* Return an array of supported extensions
*
*
* @return array
* @return array
*/
*/
public static function supportedExtensions(): array
public static function supportedExtensions(): array
{
{
$extensions = static::$imageExtensions;
$extensions = static::$imageExtensions;
if( in_array( 'WEBP', Imagick::queryFormats() ) )
if( in_array( 'WEBP', Imagick::queryFormats() ) )
{
{
$extensions[] = 'webp';
$extensions[] = 'webp';
}
}
if( in_array( 'AVIF', Imagick::queryFormats() ) )
if( in_array( 'AVIF', Imagick::queryFormats() ) )
{
{
$extensions[] = 'avif';
$extensions[] = 'avif';
}
}
return $extensions;
return $extensions;
}
}
}
}
Gespeicherte Diffs
Originaltext
Datei öffnen
<?php /** * @brief Image Class - ImageMagick * @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a> * @copyright (c) Invision Power Services, Inc. * @license https://www.invisioncommunity.com/legal/standards/ * @package Invision Community * @since 06 Mar 2014 */ namespace IPS\Image; /* To prevent PHP errors (extending class does not exist) revealing path */ use Imagick; use ImagickDraw; use ImagickException; use ImagickPixel; use InvalidArgumentException; use IPS\Image; use IPS\Settings; use function count; use function defined; use function file_put_contents; use function in_array; use const IPS\TEMP_DIRECTORY; if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * Image Class - ImageMagick */ class Imagemagick extends Image { /** * @brief Temporary filename */ protected string|null|false $tempFile = NULL; /** * @brief Imagick object */ protected Imagick $imagick; /** * Constructor * * @param string|null $contents Contents * @param bool $noImage We are creating a new instance of the object internally and are not passing an image string * @return void * @throws InvalidArgumentException */ public function __construct( ?string $contents, bool $noImage=FALSE ) { /* If we are just creating an instance of the object without passing image contents as a string, return now */ if( $noImage === TRUE ) { return; } $this->tempFile = tempnam( TEMP_DIRECTORY, 'imagick' ); file_put_contents( $this->tempFile, $contents ); try { $this->imagick = new Imagick( $this->tempFile ); /* Set quality (if image format is JPEG) */ if ( in_array( mb_strtolower( $this->imagick->getImageFormat() ), array( 'jpg', 'jpeg', 'webp', 'avif' ) ) ) { $this->imagick->setImageCompressionQuality( (int) Settings::i()->image_jpg_quality ?: 85 ); } } catch ( ImagickException $e ) { throw new InvalidArgumentException( $e->getMessage(), $e->getCode() ); } /* Set width/height */ $this->setDimensions(); } /** * Destructor * * @return void */ public function __destruct() { if( $this->tempFile !== NULL ) { unlink( $this->tempFile ); } } /** * Get Contents * * @return string */ public function __toString() { /* If possible, retain the color profiles when stripping EXIF data */ if( Settings::i()->imagick_strip_exif ) { $imageColorProfiles = array(); try { $imageColorProfiles = $this->imagick->getImageProfiles( 'icc' ); } catch( ImagickException $e ){} $this->imagick->stripImage(); if( count( $imageColorProfiles ) ) { foreach( $imageColorProfiles as $type => $profile ) { try { $this->imagick->profileImage( $type, $profile ); } catch( ImagickException $e ){} } } } return $this->imagick->getImagesBlob(); } /** * Resize * * @param int $width Width (in pixels) * @param int $height Height (in pixels) * @return void */ public function resize( int $width, int $height ) : void { $format = $this->imagick->getImageFormat(); if( mb_strtolower( $format ) == 'gif' ) { $this->imagick = $this->imagick->coalesceImages(); foreach( $this->imagick as $frame ) { $frame->thumbnailImage( $width, $height ); } /* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */ try { $this->imagick->optimizeImageLayers(); } catch( ImagickException $e ) { $this->imagick->deconstructImages(); } } else { $this->imagick->thumbnailImage( $width, $height ); } /* Set width/height */ $this->setDimensions(); } /** * Crop to a given width and height (will attempt to downsize first) * * @param int $width Width (in pixels) * @param int $height Height (in pixels) * @return void */ public function crop( int $width, int $height ) : void { $this->imagick->cropThumbnailImage( $width, $height ); /* Set width/height */ $this->setDimensions(); } /** * Crop at specific points * * @param int $point1X x-point for top-left corner * @param int $point1Y y-point for top-left corner * @param int $point2X x-point for bottom-right corner * @param int $point2Y y-point for bottom-right corner * @return void */ public function cropToPoints( int $point1X, int $point1Y, int $point2X, int $point2Y ) : void { if( mb_strtolower( $this->imagick->getImageFormat() ) === 'gif' ) { $this->imagick = $this->imagick->coalesceImages(); foreach( $this->imagick as $frame ) { $frame->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y ); $frame->setImagePage($point2X - $point1X, $point2Y - $point1Y, 0, 0); } /* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */ try { $this->imagick->optimizeImageLayers(); } catch( ImagickException $e ) { $this->imagick->deconstructImages(); } } else { $this->imagick->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y ); } /* Set width/height */ $this->setDimensions(); } /** * Impose image * * @param Image $image Image to impose * @param int $x Location to impose to, x axis * @param int $y Location to impose to, y axis * @return void */ public function impose( Image $image, int $x=0, int $y=0 ) : void { $this->imagick->compositeImage( $image->imagick, Imagick::COMPOSITE_DEFAULT, $x, $y ); } /** * Rotate image * * @param int $angle Angle of rotation * @return void */ public function rotate( int $angle ) : void { $this->imagick->rotateImage( new ImagickPixel('#00000000'), $angle ); /* Set width/height */ $this->setDimensions(); } /** * @return void */ public function flip(): void { $this->imagick->flopImage(); /* Set width/height */ $this->setDimensions(); } /** * Set the image width and height * * @return void */ protected function setDimensions() : void { /* If this is a gif, we need to coalesce the image in order to get the proper dimensions */ if ( mb_strtolower( $this->imagick->getImageFormat() ) === 'gif' ) { $this->imagick = $this->imagick->coalesceImages(); } /* Set width/height */ $this->width = $this->imagick->getImageWidth(); $this->height = $this->imagick->getImageHeight(); } /** * Get Image Orientation * * @return int|NULL */ public function getImageOrientation(): int|NULL { try { if ( $orientation = parent::getImageOrientation() ) { return $orientation; } /* This method does not exist in ImageMagick < 6.6.4 */ return ( method_exists( $this->imagick, 'getImageOrientation' ) ) ? $this->imagick->getImageOrientation() : NULL; } catch( ImagickException $e ) { return NULL; } } /** * Set image orientation * * @param int $orientation The orientation * @return void */ public function setImageOrientation( int $orientation ) : void { if( method_exists( $this->imagick, 'getImageOrientation' ) ) { $this->imagick->setImageOrientation($orientation); } } /** * Can we write text reliably on an image? * * @return bool */ public static function canWriteText(): bool { return TRUE; } /** * Create a new blank canvas image * * @param int $width Width * @param int $height Height * @param array $rgb Color to use for bg * @return Image */ public static function newImageCanvas( int $width, int $height, array $rgb ): Image { $obj = new static(NULL, TRUE); $obj->imagick = new Imagick(); $obj->width = $width; $obj->height = $height; $obj->type = 'png'; $pixel = new ImagickPixel( "rgba({$rgb[0]}, {$rgb[1]}, {$rgb[2]}, 1)" ); $obj->imagick->newImage( $width, $height, $pixel ); $obj->imagick->setImageFormat( "png" ); return $obj; } /** * Write text on our image * * @param string $text Text * @param string $font Path to font to use * @param int $size Size of text * @return void */ public function write( string $text, string $font, int $size ) : void { $draw = new ImagickDraw(); $draw->setTextAntialias( true ); $draw->setGravity( Imagick::GRAVITY_CENTER ); $draw->setFont( $font ); $draw->setFontSize( $size ); $draw->setFillColor( new ImagickPixel( "rgba(255,255,255,1)" ) ); $this->imagick->annotateImage( $draw, 0, 0, 0, $text ); } /** * Return an array of supported extensions * * @return array */ public static function supportedExtensions(): array { $extensions = static::$imageExtensions; if( in_array( 'WEBP', Imagick::queryFormats() ) ) { $extensions[] = 'webp'; } if( in_array( 'AVIF', Imagick::queryFormats() ) ) { $extensions[] = 'avif'; } return $extensions; } }
Bearbeitung
Datei öffnen
<?php /** * @brief Image Class - ImageMagick * @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a> * @copyright (c) Invision Power Services, Inc. * @license https://www.invisioncommunity.com/legal/standards/ * @package Invision Community * @since 06 Mar 2014 */ namespace IPS\Image; /* To prevent PHP errors (extending class does not exist) revealing path */ use Imagick; use ImagickDraw; use ImagickException; use ImagickPixel; use InvalidArgumentException; use IPS\Image; use IPS\Settings; use function count; use function defined; use function file_put_contents; use function in_array; use const IPS\TEMP_DIRECTORY; if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * Image Class - ImageMagick */ class Imagemagick extends Image { /** * @brief Temporary filename */ protected string|null|false $tempFile = NULL; /** * @brief Imagick object */ protected Imagick $imagick; /** * Constructor * * @param string|null $contents Contents * @param bool $noImage We are creating a new instance of the object internally and are not passing an image string * @return void * @throws InvalidArgumentException */ public function __construct( ?string $contents, bool $noImage=FALSE ) { /* If we are just creating an instance of the object without passing image contents as a string, return now */ if( $noImage === TRUE ) { return; } $this->tempFile = tempnam( TEMP_DIRECTORY, 'imagick' ); if ( $this->tempFile === FALSE ) { throw new \RuntimeException('Unable to create temporary file for ImageMagick'); } file_put_contents( $this->tempFile, $contents ); try { $this->imagick = new Imagick( $this->tempFile ); /* Set quality (if image format is JPEG, WEBP, or AVIF) */ if ( in_array( mb_strtolower( $this->imagick->getImageFormat() ), array( 'jpg', 'jpeg', 'webp', 'avif' ) ) ) { $this->imagick->setImageCompressionQuality( (int) Settings::i()->image_jpg_quality ?: 85 ); } } catch ( ImagickException $e ) { if ( $this->tempFile !== NULL && @is_file( $this->tempFile ) ) { @unlink( $this->tempFile ); } throw new InvalidArgumentException( $e->getMessage(), $e->getCode() ); } /* Set width/height */ $this->setDimensions(); } /** * Destructor * * @return void */ public function __destruct() { if( $this->tempFile !== NULL && @is_file( $this->tempFile ) ) { @unlink( $this->tempFile ); } } /** * Get Contents * * @return string */ public function __toString() { /* If possible, retain the color profiles when stripping EXIF data */ if( Settings::i()->imagick_strip_exif ) { $imageColorProfiles = array(); try { $imageColorProfiles = $this->imagick->getImageProfiles( 'icc' ); } catch( ImagickException $e ){} $this->imagick->stripImage(); if( count( $imageColorProfiles ) ) { foreach( $imageColorProfiles as $type => $profile ) { try { $this->imagick->profileImage( $type, $profile ); } catch( ImagickException $e ){} } } } return $this->imagick->getImagesBlob(); } /** * Automatically orient the image based on EXIF data * * @return void */ public function autoOrient(): void { try { $this->imagick->autoOrient(); $this->setDimensions(); error_log("Après autoOrient - Largeur: {$this->width}, Hauteur: {$this->height}"); } catch ( ImagickException $e ) { error_log("Erreur autoOrient: " . $e->getMessage()); } } /** * Resize * * @param int $width Width (in pixels) * @param int $height Height (in pixels) * @return void */ public function resize( int $width, int $height ) : void { $format = mb_strtolower( $this->imagick->getImageFormat() ); if( $format == 'gif' ) { $this->imagick = $this->imagick->coalesceImages(); foreach( $this->imagick as $frame ) { $frame->thumbnailImage( $width, $height ); } /* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */ try { $this->imagick->optimizeImageLayers(); } catch( ImagickException $e ) { $this->imagick->deconstructImages(); } } else { $this->imagick->thumbnailImage( $width, $height ); } /* Set width/height */ $this->setDimensions(); } /** * Crop to a given width and height * * @param int $width Width (in pixels) * @param int $height Height (in pixels) * @return void */ public function crop( int $width, int $height ) : void { $this->imagick->cropThumbnailImage( $width, $height ); /* Set width/height */ $this->setDimensions(); } /** * Crop at specific points * * @param int $point1X x-point for top-left corner * @param int $point1Y y-point for top-left corner * @param int $point2X x-point for bottom-right corner * @param int $point2Y y-point for bottom-right corner * @return void */ public function cropToPoints( int $point1X, int $point1Y, int $point2X, int $point2Y ) : void { $format = mb_strtolower( $this->imagick->getImageFormat() ); if( $format === 'gif' ) { $this->imagick = $this->imagick->coalesceImages(); foreach( $this->imagick as $frame ) { $frame->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y ); $frame->setImagePage( $point2X - $point1X, $point2Y - $point1Y, 0, 0 ); } /* Needs ImageMagick 6.2.9 or higher for optimizeImageLayers */ try { $this->imagick->optimizeImageLayers(); } catch( ImagickException $e ) { $this->imagick->deconstructImages(); } } else { $this->imagick->cropImage( $point2X - $point1X, $point2Y - $point1Y, $point1X, $point1Y ); } /* Set width/height */ $this->setDimensions(); } /** * Impose image * * @param Image $image Image to impose * @param int $x Location to impose to, x axis * @param int $y Location to impose to, y axis * @return void */ public function impose( Image $image, int $x=0, int $y=0 ) : void { if ( $image instanceof Imagemagick ) { $this->imagick->compositeImage( $image->imagick, Imagick::COMPOSITE_DEFAULT, $x, $y ); } } /** * Rotate image * * @param int $angle Angle of rotation * @return void */ public function rotate( int $angle ) : void { $this->imagick->rotateImage( new ImagickPixel('#00000000'), $angle ); /* Set width/height */ $this->setDimensions(); } /** * Flip image horizontally * * @return void */ public function flip(): void { $this->imagick->flopImage(); /* Set width/height */ $this->setDimensions(); } /** * Set the image width and height * * @return void */ protected function setDimensions() : void { /* If this is a gif, we need to coalesce the image in order to get the proper dimensions */ if ( mb_strtolower( $this->imagick->getImageFormat() ) === 'gif' ) { $this->imagick = $this->imagick->coalesceImages(); } /* Set width/height */ $this->width = $this->imagick->getImageWidth(); $this->height = $this->imagick->getImageHeight(); } /** * Get Image Orientation * * @return int|null */ public function getImageOrientation(): ?int { try { if ( $orientation = parent::getImageOrientation() ) { return $orientation; } /* This method does not exist in ImageMagick < 6.6.4 */ return ( method_exists( $this->imagick, 'getImageOrientation' ) ) ? $this->imagick->getImageOrientation() : null; } catch( ImagickException $e ) { return null; } } /** * Set image orientation * * @param int $orientation The orientation * @return void */ public function setImageOrientation( int $orientation ) : void { if( method_exists( $this->imagick, 'setImageOrientation' ) ) { $this->imagick->setImageOrientation( $orientation ); } } /** * Get Image Width * * @return int|null */ public function getWidth(): ?int { return $this->imagick->getImageWidth(); } /** * Get Image Height * * @return int|null */ public function getHeight(): ?int { return $this->imagick->getImageHeight(); } /** * Can we write text reliably on an image? * * @return bool */ public static function canWriteText(): bool { return true; } /** * Create a new blank canvas image * * @param int $width Width * @param int $height Height * @param array $rgb Color to use for bg * @return Image */ public static function newImageCanvas( int $width, int $height, array $rgb ): Image { $obj = new static( null, true ); $obj->imagick = new Imagick(); $obj->width = $width; $obj->height = $height; $obj->type = 'png'; $pixel = new ImagickPixel( "rgba({$rgb[0]}, {$rgb[1]}, {$rgb[2]}, 1)" ); $obj->imagick->newImage( $width, $height, $pixel ); $obj->imagick->setImageFormat( 'png' ); return $obj; } /** * Write text on our image * * @param string $text Text * @param string $font Path to font to use * @param int $size Size of text * @return void */ public function write( string $text, string $font, int $size ) : void { $draw = new ImagickDraw(); $draw->setTextAntialias( true ); $draw->setGravity( Imagick::GRAVITY_CENTER ); $draw->setFont( $font ); $draw->setFontSize( $size ); $draw->setFillColor( new ImagickPixel( 'rgba(255,255,255,1)' ) ); $this->imagick->annotateImage( $draw, 0, 0, 0, $text ); } /** * Return an array of supported extensions * * @return array */ public static function supportedExtensions(): array { $extensions = static::$imageExtensions; if( in_array( 'WEBP', Imagick::queryFormats() ) ) { $extensions[] = 'webp'; } if( in_array( 'AVIF', Imagick::queryFormats() ) ) { $extensions[] = 'avif'; } return $extensions; } }
Unterschied finden