PHP画像操作クラス


ガチガチフレームワーク第２弾。
ガチガチだから、切り分けて公開できるクラスが少ない…
業務アプリケーションで使うことを目的としたフレームワークなので、Imagemagick前提。環境選びます。

```PHP
<?php

namespace common\image;

/**
 * Image
 */
class Image
{

	/**
	 * Imagickオブジェクト
	 * @var type
	 */
	private $_objImage = null;

	/**
	 * ファイル名
	 * @var type
	 */
	private $_imageFile = null;

	/**
	 * 幅
	 * @var int
	 */
	private $_intWidth = null;

	/**
	 * 高さ
	 * @var int
	 */
	private $_intHeight = null;

	/**
	 * MimeType
	 * @var string
	 */
	private $_strMimeType = null;

	/**
	 * GPS
	 * @var array
	 */
	private $_gps = null;

	/**
	 * Exif
	 * @var array
	 */
	private $_arrExif = null;

	/**
	 * コンストラクタ
	 * @param string $strFileName
	 */
	public function __construct($strFileName = null)
	{
		$this->_objImage = new \Imagick();
		if (!is_null($strFileName) && file_exists(realpath($strFileName))) {
			$this->_imageFile = realpath($strFileName);
			$this->_readImage();
		}
	}

	/**
	 * Imagickバージョンを取得する
	 * @return string
	 */
	static public function getVersion()
	{
		return (new \Imagick)->getversion();
	}

	/**
	 * GPS情報を取得する
	 * @return array
	 */
	public function getGps()
	{
		return $this->_gps;
	}

	/**
	 * カメラの情報を取得する
	 * @return string
	 */
	public function getExifModel()
	{
		$res = array();
		$res[] = (isset($this->_arrExif['Make'])) ?
			$this->_arrExif['Make'] :
			null;
		$res[] = (isset($this->_arrExif['Model'])) ?
			$this->_arrExif['Model'] :
			null;

		return implode(' ', $res);
	}

	/**
	 * 写真の向き
	 * 1	 そのまま
	 * 2	 上下反転(上下鏡像)
	 * 3	 180度回転
	 * 4	 左右反転
	 * 5	 上下反転、時計周りに270度回転
	 * 6	 時計周りに90度回転
	 * 7	 上下反転、時計周りに90度回転
	 * 8	 時計周りに270度回転
	 * @return int
	 */
	public function getOrientation()
	{
		return (isset($this->_arrExif['Orientation'])) ?
			$this->_arrExif['Orientation'] :
			null;
	}

	/**
	 * 高度を取得する
	 * @return int
	 */
	public function getAltitude()
	{
		$altitude = (isset($this->_arrExif['GPSAltitude'])) ?
			$this->_arrExif['GPSAltitude'] :
			null;
		$arrAltitude = explode("/", $altitude);
		return (isset($arrAltitude[0])) ? $arrAltitude[0] : null;
	}

	/**
	 * 写真の向きにあわせて正立する
	 * @return \common\Image
	 */
	public function uprightByOrientation()
	{
		$background = new \ImagickPixel('none');

		switch ($this->getOrientation()) {
			case 1:
				break;
			case 2:
				$this->_objImage->transverseimage();
				break;
			case 3:
				$this->_objImage->rotateimage($background, 180);
				break;
			case 4:
				$this->_objImage->transposeimage();
				break;
			case 5:
				$this->_objImage->transverseimage();
				$this->_objImage->rotateimage($background, 270);
				break;
			case 6:
				$this->_objImage->rotateimage($background, 90);
				break;
			case 7:
				$this->_objImage->transverseimage();
				$this->_objImage->rotateimage($background, 90);
				break;
			case 8:
				$this->_objImage->rotateimage($background, 270);
				break;
		}
		return $this;
	}

	/**
	 * リサイズする
	 * @param integer $intSize
	 * @return \common\Image
	 */
	public function resize($intSize = null)
	{
		if (!is_null($intSize)) {
			$cols = $intSize;
			$rows = $intSize;
			$bestfit = true;
			$this->_objImage->scaleimage($cols, $rows, $bestfit);
		}
		return $this;
	}

	/**
	 * Exif情報を削除する
	 * @return \common\Image
	 */
	public function removeExif()
	{
		$this->_objImage->stripImage();
		return $this;
	}

	/**
	 * コメントを追加する
	 * @param string $strComment
	 * @return \common\Image
	 */
	public function addComment($strComment = null)
	{
		if (!is_null($strComment)) {
			if (0 < strlen($this->getComment())) {
				$strComment = $this->getComment() . "\n" . $strComment;
			}
			$this->_objImage->commentImage($strComment);
		}
		return $this;
	}

	/**
	 * コメントを取得する
	 * @return string
	 */
	public function getComment()
	{
		return $this->_objImage->getimageproperty('comment');
	}

	/**
	 * 圧縮品質を設定する
	 * @param integer $intQuality
	 * @return \common\Image
	 */
	public function setQuality($intQuality)
	{
		$this->_objImage->setimagecompressionquality($intQuality);
		return $this;
	}

	/**
	 * 保存する
	 * @param string $strFileName
	 */
	public function save($strFileName = 'sample.jpg')
	{
		$this->_objImage->writeImage($strFileName);
	}

	/**
	 * 画像を読み込む
	 * @return \common\Image
	 */
	private function _readImage()
	{
		$this->_objImage->readImage($this->_imageFile);
		$this->_setSize();
		$this->_setMimeType();
		$this->_setExif();
		return $this;
	}

	/**
	 * サイズを取得する
	 * @return \common\Image
	 */
	private function _setSize()
	{
		$arrSize = $this->_objImage->getImageGeometry();
		$this->_intWidth = $arrSize['width'];
		$this->_intHeight = $arrSize['height'];
		return $this;
	}

	/**
	 * MimeTypeを取得する
	 * return void
	 */
	private function _setMimeType()
	{
		$finfo = finfo_open(FILEINFO_MIME_TYPE);
		$this->_strMimeType = finfo_file(
			$finfo
			, $this->_imageFile
			, FILEINFO_MIME_TYPE
		);
	}

	/**
	 * Exifをセットする
	 * return void
	 */
	private function _setExif()
	{
		$arrType = array('image/jpeg', 'image/tiff');
		if (in_array($this->_strMimeType, $arrType)) {
			$this->_arrExif = exif_read_data($this->_imageFile, "COMPUTED");
			$this->_setGps();
		}
	}

	/**
	 * ExifからGpsをセットする
	 * return void
	 */
	private function _setGps()
	{
		$exif = $this->_arrExif;
		if (isset($exif['GPSLatitude']) && isset($exif['GPSLongitude'])) {
			$lat = "";
			$tmp = explode("/", $exif['GPSLatitude'][0]);
			$lat .= $tmp[0] . ".";
			$tmp = explode("/", $exif['GPSLatitude'][1]);
			$lat .= $tmp[0];
			$tmp = explode("/", $exif['GPSLatitude'][2]);
			$lat .= $tmp[0];

			$lon = "";
			$tmp = explode("/", $exif['GPSLongitude'][0]);
			$lon .= $tmp[0] . ".";
			$tmp = explode("/", $exif['GPSLongitude'][1]);
			$lon .= $tmp[0];
			$tmp = explode("/", $exif['GPSLongitude'][2]);
			$lon .= $tmp[0];
			$this->_gps = array($lat, $lon);
		}
	}

}
```