outputImageDir = realpath(realpath(dirname(__FILE__))); $this->outputImageType = 'jpg'; $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]; // 今回実行用の一時変数をセット $output_image_width = $this->outputImageWidth; $output_image_height = is_null($this->outputImageHeight) ? $inputImageHeight * ($output_image_width / $inputImageWidth) : $this->outputImageHeight; // GIF 画像は縮小後も GIF 画像で出力する。旧機種対応などで、機種用の画像形式に変換したい場合、expr3 に固定する。 $output_image_type = $inputImageType == IMAGETYPE_GIF ? 'gif' : $this->outputImageType; $outputImageName = sha1($inputImagePath . '_' . $this->outputImageWidth . '_' . $this->outputFileSize . '_' . $filestat['mtime']) . '.' . $output_image_type; $outputImagePath = $this->outputImageDir . '/' . $outputImageName; if ($inputImageWidth <= $output_image_width) { if ($inputImageHeight <= $output_image_height) { $output_image_width = $inputImageWidth; $output_image_height = $inputImageHeight; } else { $output_image_width = $inputImageWidth * ($output_image_height / $inputImageHeight); } } else { if ($inputImageHeight <= $output_image_height) { $output_image_height = $inputImageHeight * ($output_image_width / $inputImageWidth); } else { if ($output_image_width / $inputImageWidth < $output_image_height / $inputImageHeight) { $output_image_height = $inputImageHeight * ($output_image_width / $inputImageWidth); } else { $output_image_width = $inputImageWidth * ($output_image_height / $inputImageHeight); } } } // ファイルが存在するか確認し、存在しない場合のみ作成する if (file_exists($outputImagePath)) { $info['convert'] = FALSE; } else { // 元ファイル作成 switch ($inputImageType) { case IMAGETYPE_GIF: $tempImage = imagecreatefromgif($inputImagePath); $arrTransparentColor = $this->getTransparentColor($tempImage); if (!empty($arrTransparentColor)) { imagecolortransparent($tempImage, $arrTransparentColor); } break; case IMAGETYPE_JPEG: $tempImage = imagecreatefromjpeg($inputImagePath); break; case IMAGETYPE_PNG: $tempImage = imagecreatefrompng($inputImagePath); break; case IMAGETYPE_WBMP: $tempImage = imagecreatefromwbmp($inputImagePath); break; } if (!$tempImage) { return false; } $scale = 1.0; $outputImagePathTemp = $outputImagePath . '.tmp-' . rand(); do { // 空ファイル作成 if ($output_image_type == 'gif') { // 縮小時のノイズ防止のためインデックスカラーで処理する。特に透過色を扱う上で重要。 $outputImage = ImageCreate($output_image_width * $scale, $output_image_height * $scale); } else { $outputImage = ImageCreateTruecolor($output_image_width * $scale, $output_image_height * $scale); } ImageCopyResampled($outputImage, $tempImage, 0, 0, 0, 0, $output_image_width * $scale, $output_image_height * $scale, $inputImageWidth, $inputImageHeight); // ファイル出力 @unlink($outputImagePathTemp); switch ($output_image_type) { case 'gif': if (!empty($arrTransparentColor)) { $transparent_color_id = imagecolorexact($outputImage, $arrTransparentColor['red'], $arrTransparentColor['green'], $arrTransparentColor['blue']); imagecolortransparent($outputImage, $transparent_color_id); } imagegif($outputImage, $outputImagePathTemp); break; case 'jpg': $quality = 75; // 表示可能なファイルサイズ以下になるまで、10%ずつクオリティを調整する do { @unlink($outputImagePathTemp); imagejpeg($outputImage, $outputImagePathTemp, $quality); $quality -= 10; clearstatcache(); } while (filesize($outputImagePathTemp) > $this->outputFileSize && $quality > 0); break; case 'png': imagepng($outputImage, $outputImagePathTemp); break; case 'bmp': imagewbmp($outputImage, $outputImagePathTemp); break; default: GC_Utils_Ex::gfPrintLog('不正な画像タイプ: '); break; } // メモリ開放 imagedestroy($outputImage); $scale -= 0.1; clearstatcache(); } while (filesize($outputImagePathTemp) > $this->outputFileSize && $scale >= 0.5); rename($outputImagePathTemp, $outputImagePath); // メモリ開放 imagedestroy($tempImage); $info['convert'] = TRUE; } $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() { } /** * 透過GIFの色情報を返す * * @access private * @param resource $image imagecreatetruecolor() のような画像作成関数が返す画像リソース。 * @return array 色情報 */ function getTransparentColor($image) { $max_x = imagesx($image) - 1; $max_y = imagesy($image) - 1; for ($x = 0; $x <= $max_x; $x++) { for ($y = 0; $y <= $max_y; $y++) { $color_index = imagecolorat($image, $x, $y); $arrColors = imagecolorsforindex($image, $color_index); if ($arrColors['alpha'] !== 0) { return $arrColors; } } } return array(); } }