PHPでの画像関連のクラス

提供:wiki - PCスキルの小技・忘却防止メモ
移動: 案内, 検索

PHPでの画像関連で使うサポート用クラス。

目次

ソース

<?php
 class ClassImageSupport{
   private $newW;
   private $newH;
   private $mime;
   private $srcImg;
   
   function __construct() {
     $this->newW = 100;
     $this->newH = 100;
     $this->mime = 0;
   }
   
   function __destruct() {
     imagedestroy($this->srcImg);
     if ( isset($this->newImg) ) {
       imagedestroy($this->newImg);
     }
   }
   
   /**
    * 画像サイズのセット
    **/
   public function setNewImgSize($w, $h) {
     $this->newW = $w;
     $this->newH = $h;
     $this->newImg = imagecreatetruecolor($this->newW, $this->newH);
   }
   
   /**
    * 画像の出力
    **/
   public function viewImg() {
     switch($this->mime){
       case IMAGETYPE_JPEG:
         header('Content-Type: image/jpeg');
         imagejpeg($this->newImg);
         break;
       case IMAGETYPE_GIF:
         $bgcolor = imagecolorallocatealpha($this->srcImg, 0, 0, 0, 127);
         imagefill($this->newImg, 0, 0, $bgcolor);
         imagecolortransparent($this->newImg, $bgcolor);
         
         header('Content-Type: image/gif');
         imagegif($this->newImg);
         break;
       case IMAGETYPE_PNG:
         header('Content-Type: image/png');
         imagepng($this->newImg);
         break;
       default:
         return false;
     }
   }
   
   /**
    * 画像の保存
    **/
   public function saveImg($filePath="", $fileName="") {
     if ( $fileName == "" ) {
       $fileName = date();
     }
     $savePath = $filePath . $fileName;
     
     switch($this->mime){
       case IMAGETYPE_JPEG:
         imagejpeg($this->newImg, $savePath . '.jpg');
         break;
       case IMAGETYPE_GIF:
         $bgcolor = imagecolorallocatealpha($this->srcImg, 0, 0, 0, 127);
         imagefill($this->newImg, 0, 0, $bgcolor);
         imagecolortransparent($this->newImg, $bgcolor);
         imagegif($this->newImg, $savePath . '.gif');
         break;
       case IMAGETYPE_PNG:
         imagepng($this->newImg, $savePath . '.png');
         break;
       default:
         return false;
     }
   }
   
   /**
    * 画像の縮小
    * $imgSize  : 画像サイズ
    * $bkCol    : 背景色
    * $overflow : はみ出てもOKか
    * $pos      : 中心揃えか
    **/
   public function reduceImg($srcImg, $bkCol=array(0,0,0), $overflow=false, $pos=false) {
     // オリジナル画像の情報
     list($srcW, $srcH) = getimagesize($srcImg);
     $srcX = 0;
     $srcY = 0;
     
     // 画像縮小時のメモリ割り当て
     $this->setMemoryForImage($srcImg);
     
     // MIMEタイプを取得する
     $this->mime = $this->getMimeType($srcImg);
     
     // オリジナル画像
     switch($this->mime){
       case IMAGETYPE_JPEG:
         $this->srcImg = imagecreatefromjpeg($srcImg);
         break;
       case IMAGETYPE_GIF:
         $this->srcImg = imagecreatefromgif($srcImg);
         break;
       case IMAGETYPE_PNG:
         imagealphablending($this->newImg, false);
         imagesavealpha($this->newImg, true);
         $this->srcImg = imagecreatefrompng($srcImg);
         break;
       default:
         return false;
     }
     
     // 画像枠の背景色
     list($r, $g, $b) = $bkCol;
     imagefilledrectangle($this->newImg, 0, 0, $this->newW, $this->newH, imagecolorallocate($this->newImg, $r, $g, $b));
     
     // オリジナル画像の拡大・縮小後のサイズ
     list($resizeW, $resizeH) = $this->getSizeOfReduceImg($srcW, $srcH, $this->newW, $this->newH, $overflow);
     
     // キャンバスの表示開始座標
     list($canvasX, $canvasY) = $this->getViewPositionOfCanvas($this->newW, $this->newH, $resizeW, $resizeH, $pos);
     
     imagecopyresampled( $this->newImg,      // キャンバス
                         $this->srcImg,      // オリジナル画像
                         $canvasX, $canvasY, // キャンバスの座標
                         $srcX,    $srcY,    // オリジナルの座標
                         $resizeW, $resizeH, // 拡大・縮小したときの幅 / 高さ
                         $srcW,    $srcH     // オリジナルの幅 / 高さ
                    );
   }
   
   /**
    * フォームから読み込まれた画像のチェック
    */
   public static function chkImage($imgObj) {
     // 画像の読み取り: $imgObj['error'] の値を確認
     switch ( $imgObj['error'] ) {
       case UPLOAD_ERR_OK: // OK
         $chkReadImg = 'success';
         break;
       case UPLOAD_ERR_NO_FILE:
         $chkReadImg = 'ファイルが選択されていません';
         break;
       case UPLOAD_ERR_INI_SIZE:
       case UPLOAD_ERR_FORM_SIZE:
         // php.ini定義、フォーム定義の最大サイズ超過
         $chkReadImg = 'ファイルサイズが大きすぎます';
         break;
       default:
         $chkReadImg = 'その他のエラーが発生しました';
         break;
     }
     
     return $chkReadImg;
   }
   
   /**
    * $_FILES['upfile']['mime']の値は
    * ブラウザ側で偽装可能なので
    * MIMEタイプを自前でチェックする
    **/
   public function getMimeType($srcImg) {
     $chkReadImg = array('code'=>'start', 'mime'=>"");
     
     if ( !in_array( $type = @exif_imagetype($srcImg),
                     array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG ),
                     true
                   )
     ) {
       $mime = false;
     }
     else {
       $mime = $type;
     }
     
     return $mime;
   }
   
   /**
    * 画像縮小時のメモリ割り当て
    **/
   private function setMemoryForImage( $filename ){
     $imageInfo = getimagesize($filename);
     
     $MB          = 1048576; // number of bytes in 1M
     $K64         = 65536;   // number of bytes in 64K
     $TWEAKFACTOR = 1.5;     // Or whatever works for you
     
     $ch = (isset($imageInfo['channels']))? $imageInfo['channels']: 3;
     
     $memoryNeeded = round( ( $imageInfo[0]
                              * $imageInfo[1]
                              * $imageInfo['bits']
                              * $ch / 8
                              + $K64
                            ) * $TWEAKFACTOR
                          );
      
     $memoryLimit = 8 * $MB;
     if (function_exists('memory_get_usage') && memory_get_usage() + $memoryNeeded > $memoryLimit) {
       $newLimit = $memoryLimit * $MB + ceil( ( memory_get_usage() + $memoryNeeded - $memoryLimit ) / $MB );
       ini_set( 'memory_limit', $newLimit . 'M' );
       return true;
     }
     else {
       return false;
     }
   }
   
   /**
    * 出力時の表示位置
    * src: 出力先の画像リンクリソース
    * dst: 表示する画像
    * pos: 出力先が小さい時(はみでる場合)の画像の表示位置
    *    - true:  表示位置を「X=0,Y=0」にする
    *    - false: 中心にする
    **/
   private function getViewPositionOfCanvas($srcW, $srcH, $dstW, $dstH, $pos=true) {
     if ( $pos && $srcW < $dstW ) {
       $viewX = 0;
     }
     else {
       $viewX = round( ($srcW / 2) - ($dstW / 2) );
     }
     
     if ( $pos && $srcH < $dstH ) {
       $viewY = 0;
     }
     else {
       $viewY = round( ($srcH / 2) - ($dstH / 2) );
     }
     
     return array($viewX, $viewY);
   }
   
   /**
    * 画像を縮小した際の幅・高さの取得
    * ※元画像より大きくはしない。
    * src:      コピー元
    * dst:      コピー先
    * overflow: true  - 画像がはみでてもOK
    *           false - 画像がはみでるのはNG
    **/
   private function getSizeOfReduceImg($srcW, $srcH, $dstW, $dstH, $overflow) {
     $tmpW = $srcW;
     $tmpH = $srcH;
     
     if ( $overflow ) {
       // 幅、高さ共に大きいときのみ縮小
       if ( $dstW < $srcW && $dstH < $srcH ) {
         $ratioW = ( $dstW < $srcW )? $dstW / $srcW: 1;
         $ratioH = ( $dstH < $srcH )? $dstH / $srcH: 1;
         
         if ( $ratioW < $ratioH ) {
           // 高さのほうが縮小率が大きい場合
           $tmpW = round( $ratioH * $srcW );
           $tmpH = $dstH;
         }
         else {
           // 幅のほうが縮小率が大きい場合
           $tmpW = $dstW;
           $tmpH = round( $ratioW * $srcH );
         }
       }
     }
     else {
       if ( $dstW < $srcW ) {
         $tmpW = $dstW;
         $tmpH = round( ($dstW / $srcW) * $srcH );
       }
       else {
         $tmpW = $srcW;
         $tmpH = $srcH;
       }
       
       // 縦幅が規定より大きい場合は再度縮小
       if ( $dstH < $tmpH ) {
         $tmpW = round( ($dstH / $tmpH) * $tmpW );
         $tmpH = $dstH;
       }
     }
     
     return array($tmpW, $tmpH);
   }
   
 }

画像のURLやPATHから利用するとき

$objImg = new ClassImageSupport();

$newW = 190;
$newH = 130;
$objImg->setNewImgSize($newW, $newH);

$bkCol    = array(125, 200, 300);
$overflow = true;
$pos      = false;
$objImg->reduceImg('glide1.jpg', $bkCol, $overflow, $pos);

$objImg->viewImg();
// $objImg->saveImg("", 'abcd');

unset($objImg);

formでアップした画像をどうこうするとき

if(isset($_POST["create"])){
  $objImg = new ClassImageSupport();
  
  if ( ($err = $objImg->chkImage($_FILES["img"])) != 'success' ) {
    echo $err;
  }
  else {
    $newW = 500;
    $newH = 500;
    $objImg->setNewImgSize($newW, $newH);
    
    $bkCol    = array(125, 200, 300);
    $overflow = true;
    $pos      = false;
    $objImg->reduceImg($_FILES["img"]["tmp_name"], $bkCol, $overflow, $pos);
    
    $objImg->viewImg();
    // $objImg->saveImg("", '0123');
    
    unset($objImg);
  }
}

▼formで使う時のHTML

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
</head>
<body>

<form action="" method="post" enctype="multipart/form-data">
  <input type="file" name="img" /><br>
  <input type="submit" value="送信" name="create"/>
</form>
</body>
</html>

関連項目