Changeset 20973


Ignore:
Timestamp:
2011/06/11 17:03:57 (13 years ago)
Author:
Seasoft
Message:

#597 (画像サイズ変更で透過GIFが扱えない)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_11-dev/data/include/image_converter.inc

    r20116 r20973  
    1313    function ImageConverter() { 
    1414        $this->outputImageDir    = realpath(realpath(dirname(__FILE__))); 
    15         $this->outputImageType   = 'jpeg'; 
     15        $this->outputImageType   = 'jpg'; 
    1616        $this->outputImageWidth  = 320; 
    1717        $this->outputImageHeight = NULL; 
     
    2727        $inputImageHeight = $imagesize[1]; 
    2828        $inputImageType   = $imagesize[2]; 
     29 
     30        // GIF 画像は縮小後も GIF 画像で出力する。旧機種対応などで、機種用の画像形式に変換したい場合、この処理は削除する。 
     31        if ($inputImageType == IMAGETYPE_GIF) { 
     32            $this->outputImageType = 'gif'; 
     33        } 
     34 
    2935        $outputImageName  = sha1($inputImagePath . '_' . $this->outputImageWidth . '_' . $this->outputFileSize . '_' . $filestat['mtime']) . '.' . $this->outputImageType; 
    3036        $outputImagePath  = $this->outputImageDir . '/' . $outputImageName; 
     
    6167            // 元ファイル作成 
    6268            switch($inputImageType) { 
    63             case 1: 
    64                 // gif 
    65                 $tempImage = imagecreatefromgif($inputImagePath); 
    66                 break; 
    67             case 2: 
    68                 // jpeg 
    69                 $tempImage = imagecreatefromjpeg($inputImagePath); 
    70                 break; 
    71             case 3: 
    72                 // png 
    73                 $tempImage = imagecreatefrompng($inputImagePath); 
    74                 break; 
    75             case 6: 
    76                 // bmp 
    77                 $tempImage = imagecreatefromwbmp($inputImagePath); 
    78                 break; 
     69                case IMAGETYPE_GIF: 
     70                    $tempImage = imagecreatefromgif($inputImagePath); 
     71                    $arrTransparentColor = $this->getTransparentColor($tempImage); 
     72                    if (!empty($arrTransparentColor)) { 
     73                        imagecolortransparent($tempImage, $arrTransparentColor); 
     74                    } 
     75                    break; 
     76 
     77                case IMAGETYPE_JPEG: 
     78                    $tempImage = imagecreatefromjpeg($inputImagePath); 
     79                    break; 
     80 
     81                case IMAGETYPE_PNG: 
     82                    $tempImage = imagecreatefrompng($inputImagePath); 
     83                    break; 
     84 
     85                case IMAGETYPE_WBMP: 
     86                    $tempImage = imagecreatefromwbmp($inputImagePath); 
     87                    break; 
    7988            } 
    8089 
     
    8796            do { 
    8897                // 空ファイル作成 
    89                 $outputImage = ImageCreateTruecolor($this->outputImageWidth * $scale, $this->outputImageHeight * $scale); 
     98                if ($this->outputImageType == 'gif') { 
     99                    // 縮小時のノイズ防止のためインデックスカラーで処理する。特に透過色を扱う上で重要。 
     100                    $outputImage = ImageCreate($this->outputImageWidth * $scale, $this->outputImageHeight * $scale); 
     101                } else { 
     102                    $outputImage = ImageCreateTruecolor($this->outputImageWidth * $scale, $this->outputImageHeight * $scale); 
     103                } 
     104 
    90105                ImageCopyResampled($outputImage, $tempImage, 0, 0, 0, 0, $this->outputImageWidth * $scale, $this->outputImageHeight * $scale, $inputImageWidth, $inputImageHeight); 
    91106 
     
    95110 
    96111                switch ($this->outputImageType) { 
    97                 case 1: 
    98                 case 'gif': 
    99                     imagegif($outputImage, $outputImagePathTemp); 
    100                     break; 
    101                 default: 
    102                 case 2: 
    103                 case 'jpg': 
    104                 case 'jpeg': 
    105                     $quality = 75; 
    106                     // 表示可能なファイルサイズ以下になるまで、10%ずつクオリティを調整する 
    107                     do { 
    108                         @unlink($outputImagePathTemp); 
    109                         imagejpeg($outputImage, $outputImagePathTemp, $quality); 
    110                         $quality -= 10; 
    111                         clearstatcache(); 
    112                     } while (filesize($outputImagePathTemp) > $this->outputFileSize && $quality > 0); 
    113                     break; 
    114                 case 3: 
    115                 case 'png': 
    116                     imagepng($outputImage, $outputImagePathTemp); 
    117                     break; 
    118                 case 6: 
    119                 case 'bmp': 
    120                     imagewbmp($outputImage, $outputImagePathTemp); 
    121                     break; 
     112                    case 'gif': 
     113                        if (!empty($arrTransparentColor)) { 
     114                            $transparent_color_id = imagecolorexact($outputImage, $arrTransparentColor['red'], $arrTransparentColor['green'], $arrTransparentColor['blue']); 
     115                            imagecolortransparent($outputImage, $transparent_color_id); 
     116                        } 
     117                        imagegif($outputImage, $outputImagePathTemp); 
     118                        break; 
     119 
     120                    case 'jpg': 
     121                        $quality = 75; 
     122                        // 表示可能なファイルサイズ以下になるまで、10%ずつクオリティを調整する 
     123                        do { 
     124                            @unlink($outputImagePathTemp); 
     125                            imagejpeg($outputImage, $outputImagePathTemp, $quality); 
     126                            $quality -= 10; 
     127                            clearstatcache(); 
     128                        } while (filesize($outputImagePathTemp) > $this->outputFileSize && $quality > 0); 
     129                        break; 
     130 
     131                    case 'png': 
     132                        imagepng($outputImage, $outputImagePathTemp); 
     133                        break; 
     134 
     135                    case 'bmp': 
     136                        imagewbmp($outputImage, $outputImagePathTemp); 
     137                        break; 
     138 
     139                    default: 
     140                        GC_Utils_Ex::gfPrintLog('不正な画像タイプ: '); 
     141                        break; 
    122142                } 
    123143 
     
    165185    function beforeExecute() { 
    166186    } 
     187 
     188    /** 
     189     * 透過GIFの色情報を返す 
     190     * 
     191     * @access private 
     192     * @param resource $image imagecreatetruecolor() のような画像作成関数が返す画像リソース。 
     193     * @return array 色情報 
     194     */ 
     195    function getTransparentColor($image) { 
     196        $max_x = imagesx($image) - 1; 
     197        $max_y = imagesy($image) - 1; 
     198        for ($x = 0; $x <= $max_x; $x++) { 
     199            for ($y = 0; $y <= $max_y; $y++) { 
     200                $color_index = imagecolorat($image, $x, $y); 
     201                $arrColors = imagecolorsforindex($image, $color_index); 
     202                if ($arrColors['alpha'] !== 0){ 
     203                    return $arrColors; 
     204                } 
     205            } 
     206        } 
     207        return array(); 
     208    } 
    167209} 
    168210?> 
Note: See TracChangeset for help on using the changeset viewer.