<?php
/**
 * 画像ファイルの変換を行う
 */
class ImageConverter {
	var $outputImageDir;		// 変換後の画像の保存先
	var $outputImageType;		// 変換後の画像の形式
	var $outputImageWidth;		// 変換後の画像の横幅
	var $outputImageHeight;		// 変換後の画像の高さ
	var $outputImageFileSize;	// 変換後の画像のファイルサイズ

	// コンストラクタ
	function ImageConverter() {
		$this->outputImageDir    = realpath(realpath(dirname(__FILE__)));
		$this->outputImageType   = 'jpeg';
		$this->outputImageWidth  = 320;
		$this->outputImageHeight = NULL;
		$this->outputFileSize    = 20000;
	}

	// 変換実行
	function execute($inputImagePath) {
		// 前処理
		$filestat         = @stat($inputImagePath);
		$imagesize        = getimagesize($inputImagePath);
		$inputImageWidth  = $imagesize[0];
		$inputImageHeight = $imagesize[1];
		$inputImageType   = $imagesize[2];
		$outputImageName  = sha1($inputImagePath . '_' . $this->outputImageWidth . '_' . $this->outputFileSize . '_' . $filestat['mtime']) . '.' . $this->outputImageType;
		$outputImagePath  = $this->outputImageDir . '/' . $outputImageName;

		if (is_null($this->outputImageHeight)) {
		  $height_was_null = TRUE;
		  $this->outputImageHeight = $inputImageHeight * ($this->outputImageWidth / $inputImageWidth);
		} else {
		  $height_was_null = FALSE;
		}
		if ($inputImageWidth <= $this->outputImageWidth) {
		  if ($inputImageHeight <= $this->outputImageHeight) {
		    $this->outputImageWidth  = $inputImageWidth;
		    $this->outputImageHeight = $inputImageHeight;
		  } else {
		    $this->outputImageWidth = $inputImageWidth * ($this->outputImageHeight / $inputImageHeight);
		  }
		} else {
		  if ($inputImageHeight <= $this->outputImageHeight) {
		    $this->outputImageHeight = $inputImageHeight * ($this->outputImageWidth / $inputImageWidth);
		  } else {
		    if ($this->outputImageWidth / $inputImageWidth < $this->outputImageHeight / $inputImageHeight) {
		      $this->outputImageHeight = $inputImageHeight * ($this->outputImageWidth / $inputImageWidth);
		    } else {
		      $this->outputImageWidth = $inputImageWidth * ($this->outputImageHeight / $inputImageHeight);
		    }
		  }
		}

		// ファイルが存在するか確認し、存在しない場合のみ作成する
		if (file_exists($outputImagePath)) {
			$info['convert'] = FALSE;
		} else {
			// 元ファイル作成
			switch($inputImageType) {
			case 1:
				// gif
				$tempImage = imagecreatefromgif($inputImagePath);
				break;
			case 2:
				// jpeg
				$tempImage = imagecreatefromjpeg($inputImagePath);
				break;
			case 3:
				// png
				$tempImage = imagecreatefrompng($inputImagePath);
				break;
			case 6:
				// bmp
				$tempImage = imagecreatefromwbmp($inputImagePath);
				break;
			}

			if (!$tempImage) {
				return false;
			}

			$scale = 1.0;
			$outputImagePathTemp = $outputImagePath . '.tmp-' . rand();
			do {
				// 空ファイル作成
				$outputImage = ImageCreateTruecolor($this->outputImageWidth * $scale, $this->outputImageHeight * $scale);
				ImageCopyResampled($outputImage, $tempImage, 0, 0, 0, 0, $this->outputImageWidth * $scale, $this->outputImageHeight * $scale, $inputImageWidth, $inputImageHeight);

				// ファイル出力

				@unlink($outputImagePathTemp);

				switch ($this->outputImageType) {
				case 1:
				case 'gif':
					imagegif($outputImage, $outputImagePathTemp);
					break;
				default:
				case 2:
				case 'jpg':
				case 'jpeg':
					$quality = 75;
					// 表示可能なファイルサイズ以下になるまで、10%ずつクオリティを調整する
					do {
						@unlink($outputImagePathTemp);
						imagejpeg($outputImage, $outputImagePathTemp, $quality);
						$quality -= 10;
						clearstatcache();
					} while (filesize($outputImagePathTemp) > $this->outputFileSize && $quality > 0);
					break;
				case 3:
				case 'png':
					imagepng($outputImage, $outputImagePathTemp);
					break;
				case 6:
				case 'bmp':
					imagewbmp($outputImage, $outputImagePathTemp);
					break;
				}

				// メモリ開放
				imagedestroy($outputImage);

				$scale -= 0.1;
				clearstatcache();
			} while (filesize($outputImagePathTemp) > $this->outputFileSize && $scale >= 0.5);

			rename($outputImagePathTemp, $outputImagePath);

			// メモリ開放
			imagedestroy($tempImage);

			$info['convert'] = TRUE;
		}

		if ($height_was_null) {
		    $this->outputImageHeigh = NULL;
		}

		$info['outputImagePath']  = $outputImagePath;
		$info['outputImageName']  = $outputImageName;
		return $info;

	}

	// Setter
	function setOutputDir($outputDir)   { $this->outputImageDir   = $outputDir;  }
	function setImageType($imageType)   { $this->outputImageType  = $imageType;  }
	function setImageWidth($imageWidth) { $this->outputImageWidth = $imageWidth; }
	function setImageHeight($imageHeight) { $this->outputImageHeight = $imageHeight; }
	function setFileSize($fileSize)     { $this->outputFileSize   = $fileSize;   }

	// Getter
	function getOutputDir()   { return $this->outputDir;         }
	function getImageType()   { return $this->outputImageType;   }
	function getImageWidth()  { return $this->outputImageWidth;  }
	function getImageHeight() { return $this->outputImageHeight; }

	/*
	 * PrivateMethod
	 */
	function beforeExecute() {
	}
}
?>
