現在の言語: 日本語

戻る

ImageMagick
画像関連

phpinfo();
を実行した結果を検索して
imagick
のキーワードが存在しているか?を判定します。
存在していない場合は、php.iniの「imagick」が無効(コメントアウト)になっている可能性があります。

[php.iniの場所]
echo "ini path:".php_ini_loaded_file();
上記を実行した後で出力された結果からphp.iniの場所を編集することになります。
※編集前にphp.iniファイルのバックアップをとっておくことを、お勧めします。
(例)
ini path:/Applications/MAMP/bin/php/php8.2.0/conf/php.ini

php.iniを探すと下記のように設定されているステップがあると思います。

;extension=imagick.so
「;」はコメントアウトにする記号ですので、この「;」を外します。
(例)
extension=imagick.so;20260128 mod コメントアウトを外した
;extension=imagick.so

この結果を保存した後、Apacheを再起動します。
phpinfo();を再実行後
imagickがphpinfoの結果で表示されると、
ImageMagickが使用可能の状態になります。

Imagickが使えるメリット

[エラーに強い]
GDで読み込めない微妙な破損画像も、内部的に修復して開いてくれることが多いです。

[高品質]
FILTER_LANCZOS などの高度な計算手法が使えるため、縮小しても画像がボケにくいです。

[多機能]
PDFやWebPなど、PNG/JPG以外の形式も同じ書き方で扱えます。

通常はファイル形式を明示して読み込ませるのですが。
稀に開けないことがあり、その場合バイナリとして読み込ませることで
ファイルが開ける可能性があります。
今回のサンプルはバイナリで読み込ませる方法となります。

[サンプル]

copy
$kind = 1;//0;//[0]png [1]jpg
$input_dir = "./img/";//変換元となる画像フォルダパス
$output_dir = "./img/out/";//変換先に出力する画像フォルダパス
$imageSize = 300;//px単位
//画像リサイズ変換処理
resizeImageImageMagick($kind, $input_dir, $output_dir, $imageSize);
//phpinfo();

//画像リサイズ変換処理
//kind:[0]png [1]jpg
//input_dir:変換元となる画像フォルダパス
//output_dir:変換先に出力する画像フォルダパス
//imageSize:px単位
function resizeImageImageMagick(int $kind, string $input_dir, string $output_dir, int $imageSize)
{
	$all_files = scandir($input_dir);
	$files = [];

	//指定したフォルダの画像ファイルID(拡張子がpngもしくはjpg)を取得する処理
	imageDir($kind, $input_dir, $files);

	if(count($files)==0)
	{
		echo "対象ファイルが存在しません。\n";
		return;
	}

	// 保存先フォルダがなければ作成する
	if (!is_dir($output_dir))
	{
		mkdir($output_dir, 0755, true);
	}

	//画像サイズ変更
	resizeImage($kind, $input_dir, $output_dir, $imageSize, $files);
}

//画像サイズ変更
function resizeImage(int $kind, string $input_dir, string $output_dir, int $imageSize, array &$files)
{
	$src_image = null;
	foreach ($files as $file) 
	{
		echo "file:$file\n";
		if(!file_exists($input_dir . $file))
		{
			echo "ファイルは存在しないので次のファイルを判定します。\n";
			continue;
		}
		$image_into = getimagesize($input_dir . $file);
		if($image_into === false)
		{
			if(($kind == 0 && $image_into[2] !== IMAGETYPE_PNG) || 
			($kind == 1 && $image_into[2] !== IMAGETYPE_JPEG)
			)
			{
				echo "画像情報が誤っています。\n";
				continue;
			}
		}
		// 3. ファイル名を取得(元のファイル名と同じ名前で保存するため)
		$filename = basename($input_dir . $file);
		$save_path = $output_dir . $filename;

		// 4. 指定したフォルダに直接保存
		// imagepngの第2引数にパスを渡すと、ファイルとして書き出されます
		if($kind == 0)
		{
			$ext = "png";
		}
		else
		{
			$ext = "jpg";
		}
		try 
		{
			//インスタンス作成(GDのimagecreatefrom...より読み込み能力が高い)
			$img_tmp = file_get_contents($input_dir . $file);
			$image = new Imagick();
			//ファイルからではなく、データとして読み込み
			$image->readImageBlob($img_tmp);
			//リサイズ(幅、高さ0で比率維持、高品質フィルタ使用)
			$image->resizeImage($imageSize, 0, Imagick::FILTER_LANCZOS, 1);
			//フォーマットをPNG/JPGに明示的に設定
			$image->setImageFormat($ext);
			//指定のフォルダに保存
			$image->writeImage($save_path);
			//メモリ解放
			$image->clear();
			echo "処理が成功しました\n";
		}
		catch (Exception $e)
		{
			// Imagickでも読み込めないほど破損している場合
			echo "エラー: " . $e->getMessage()."\n";
			continue;
		}
		echo "保存完了: " . $save_path . "\n";
	}    
}
//指定したフォルダの画像ファイルID(拡張子がpngもしくはjpg)を取得する処理
//kind:[0]png [1]jpg
//input_dir:指定するフォルダパス
//files:取得したファイルIDの結果を格納する配列
function imageDir(int $kind, string $input_dir, array &$files)
{
	$all_files = scandir($input_dir);
	$files = [];

	$flg=0;
	foreach ($all_files as $file) 
	{
		$flg=0;
		if($kind==0)
		{
			// '/i' 修飾子をつけることで大文字小文字を区別せずに検索
			if (preg_match('/\.png$/i', $file)) 
			{
				$flg=1;
			}
		}
		else
		{
			//最も一般的な書き方(OR演算子)
			// (jpg|jpeg) で「jpg」または「jpeg」にマッチ
			//if (preg_match('/\.(jpg|jpeg)$/i', $file))

			//短く書く方法(量指定子 ?)
			// jpe?g で「jpg」と「jpeg」の両方にマッチ
			if (preg_match('/\.jpe?g$/i', $file)) 
			{
				$flg=1;
			}
		}
		if($flg==0)continue;
		$files[] = $file;
	}

}
copy
$kind = 1;//0;//[0]png [1]jpg
$input_dir = "./img/";//Source image folder path
$output_dir = "./img/out/";//Destination image folder path
$imageSize = 300;//Pixel units
//Image resizing process
resizeImageImageMagick($kind, $input_dir, $output_dir, $imageSize);
//phpinfo();

//Image resizing process
//kind:[0]png [1]jpg
//input_dir:Source image folder path
//output_dir:Destination image folder path
//imageSize:Pixel units
function resizeImageImageMagick(int $kind, string $input_dir, string $output_dir, int $imageSize)
{
	$all_files = scandir($input_dir);
	$files = [];
	
	//Get image file IDs (with extensions .png or .jpg) in the specified folder
	imageDir($kind, $input_dir, $files);
	
	if(count($files)==0)
	{
		echo "The target file does not exist.\n";
		return;
	}
	
	//Create the destination folder if it does not exist
	if (!is_dir($output_dir))
	{
		mkdir($output_dir, 0755, true);
	}
	
	//Resize the image
	resizeImage($kind, $input_dir, $output_dir, $imageSize, $files);
}

//Resize the image
function resizeImage(int $kind, string $input_dir, string $output_dir, int $imageSize, array &$files)
{
	$src_image = null;
	foreach ($files as $file)
	{
	echo "file:$file\n";
	if(!file_exists($input_dir . $file))
	{
		echo "The file does not exist, so the next file will be checked.\n";
		continue;
	}
	$image_into = getimagesize($input_dir . $file);
	if($image_into === false)
	{
		if(($kind == 0 && $image_into[2] !== IMAGETYPE_PNG) ||
		($kind == 1 && $image_into[2] !== IMAGETYPE_JPEG)
		)
		{
			echo "The image information is incorrect.\n";
			continue;
		}
	}
	// 3. Get the file name (to save it with the same name as the original).
	$filename = basename($input_dir . $file);
	$save_path = $output_dir . $filename;
	
	// 4. Save directly to the specified folder.
	// If you pass a path to the second argument of imagepng, it will be written as a file.
	if($kind == 0)
	{
		$ext = "png";
	}
	else
	{
		$ext = "jpg";
	}
	try
	{
		//Create an instance (higher read performance than GD's imagecreatefrom...)
		$img_tmp = file_get_contents($input_dir . $file);
		$image = new Imagick();
		//Read as data, not from a file
		$image->readImageBlob($img_tmp);
		//Resize (set width and height to 0, maintain ratio, use high-quality filter)
		$image->resizeImage($imageSize, 0, Imagick::FILTER_LANCZOS, 1);
		//Explicitly set the format to PNG/JPG
		$image->setImageFormat($ext);
		//Save to a specified folder
		$image->writeImage($save_path);
		//Free memory
		$image->clear();
		echo "The operation was successful\n";
	}
	catch (Exception $e)
	{
		// If the file is corrupted to the point that even Imagick cannot read it:
		echo "Error: " . $e->getMessage()."\n";
		continue;
	}
		echo "Saved: " . $save_path . "\n";
	}
}
//Get image file IDs (with extensions .png or .jpg) in the specified folder.
//kind:[0]png [1]jpg
//input_dir:Specified folder path
//files:Array to store the retrieved file IDs.
function imageDir(int $kind, string $input_dir, array &$files)
{
	$all_files = scandir($input_dir);
	$files = [];
	
	$flg=0;
	foreach ($all_files as $file)
	{
		$flg=0;
		if($kind==0)
		{
			//Add the '/i' modifier to perform a case-insensitive search.
			if (preg_match('/\.png$/i', $file))
			{
				$flg=1;
			}
		}
		else
		{
			// Most common syntax (OR operator)
			// (jpg|jpeg) matches "jpg" or "jpeg"
			//if (preg_match('/\.(jpg|jpeg)$/i', $file))
			
			// Shorter syntax (quantifier ?)
			// jpe?g matches both "jpg" and "jpeg"
			if (preg_match('/\.jpe?g$/i', $file))
			{
				$flg=1;
			}
		}
		if($flg==0)continue;
		$files[] = $file;
	}

}
try...catchで実装することにより、
一つの破損ファイルでプログラムを止めないようにスキップするのが一般的です。

readImageBlob
ファイルパスを渡して直接開くのではなく、一旦 file_get_contents でデータをメモリに読み込み、
それを Imagick に設定する方法です。
blobにすることで厳格なヘッダーチェックを回避できる場合があります。

$image->readImageBlob($img_tmp);
ファイルからではなく、データとして読み込みます。


戻る

著作権情報
ホームページおよびアプリ等に掲載されている情報等については、いかなる保障もいたしません。
ホームページおよびアプリ等を通じて入手したいかなる情報も複製、販売、出版または使用させたり、
または公開したりすることはできません。
当方は、ホームページおよびアプリ等を利用したいかなる理由によっての障害等が発生しても、
その結果ホームページおよびアプリ等を利用された本人または他の第三者が被った損害について
一切の責任を負わないものとします。