Diff
checker
文本
文本
图像
文档
Excel
文件夹
Legal
Enterprise
桌面版
定价
登录
下载 Diffchecker 桌面版
比较文本
查找两个文本文件之间的差异
工具
历史
实时编辑器
折叠未更改行
关闭换行
视图
拆分
统一
比对精度
智能
单词
字符
语法高亮
选择语法
忽略
文本转换
转到第一个差异
编辑输入
Diffchecker Desktop
运行Diffchecker最安全的方式。获取Diffchecker桌面应用:您的差异永远不会离开您的电脑!
获取桌面版
Imagemagick.php
创建于
10个月前
差异永不过期
清除
导出
分享
解释
33 删除
行
总计
删除
字符
总计
删除
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
397 行
全部复制
88 添加
行
总计
添加
字符
总计
添加
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
451 行
全部复制
<?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' );
复制
已复制
复制
已复制
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 );
复制
已复制
复制
已复制
/* 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 )
{
{
复制
已复制
复制
已复制
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()
{
{
复制
已复制
复制
已复制
if( $this->tempFile !== NULL
)
if( $this->tempFile !== NULL
&& @is_file( $this->tempFile )
)
{
{
复制
已复制
复制
已复制
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 )
{
{
复制
已复制
复制
已复制
$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();
}
}
/**
/**
复制
已复制
复制
已复制
* 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
*
*
复制
已复制
复制
已复制
* @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
{
{
复制
已复制
复制
已复制
$format =
$this->imagick->getImageFormat()
;
$format =
mb_strtolower(
$this->imagick->getImageFormat()
)
;
复制
已复制
复制
已复制
if(
mb_strtolower(
$format
)
== 'gif' )
if(
$format
== 'gif' )
{
{
复制
已复制
复制
已复制
$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();
}
}
/**
/**
复制
已复制
复制
已复制
* Crop to a given width and height
(will attempt to downsize first)
* Crop to a given width and height
*
*
复制
已复制
复制
已复制
* @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
*
*
复制
已复制
复制
已复制
* @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
{
{
复制
已复制
复制
已复制
if(
mb_strtolower( $this->imagick->getImageFormat() )
=== 'gif' )
$format =
mb_strtolower( $this->imagick->getImageFormat() )
;
if( $format
=== 'gif' )
{
{
复制
已复制
复制
已复制
$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 );
复制
已复制
复制
已复制
$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
{
{
复制
已复制
复制
已复制
$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();
}
}
/**
/**
复制
已复制
复制
已复制
* 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
*
*
复制
已复制
复制
已复制
* @return int|
NULL
* @return int|
null
*/
*/
复制
已复制
复制
已复制
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 */
复制
已复制
复制
已复制
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 )
{
{
复制
已复制
复制
已复制
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
{
{
复制
已复制
复制
已复制
if( method_exists( $this->imagick, '
g
etImageOrientation' ) )
if( method_exists( $this->imagick, '
s
etImageOrientation' ) )
{
{
复制
已复制
复制
已复制
$this->imagick->setImageOrientation(
$orientation
);
$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?
* Can we write text reliably on an image?
*
*
* @return bool
* @return bool
*/
*/
public static function canWriteText(): bool
public static function canWriteText(): bool
{
{
复制
已复制
复制
已复制
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
{
{
复制
已复制
复制
已复制
$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 );
复制
已复制
复制
已复制
$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
{
{
复制
已复制
复制
已复制
$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 );
复制
已复制
复制
已复制
$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;
}
}
}
}
已保存差异
原始文本
打开文件
<?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; } }
更改后文本
打开文件
<?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; } }
查找差异