勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

画像をアップロードすると複数サムネイルを生成する方法

   2024/04/18  PHP

フォームで画像をアップロードすると、予め定めておいた大中小のサイズでサムネイル画像を生成する方法のメモ。

 

ソースコード

<?php
$resizeList = array(
    0 => array(
        'width' => '500', 
        'height' => '500', 
        'title' => 'サイズ大', 
    ),
    1 => array(
        'width' => '300', 
        'height' => '300', 
        'title' => 'サイズ中', 
    ),
    2 => array(
        'width' => '100', 
        'height' => '100', 
        'title' => 'サイズ小', 
    ),
);

define('MAIN_PATH','/var/www/html');
define('IMAGE_PATH', MAIN_PATH.'/test/img_resize/img/');
define('TMP_PATH', MAIN_PATH.'/test/img_resize/tmp/');

/* ランダム英数字作成 
 * 引数 $length(int)
 * 返り値 false or string
 */
function randomStr ($length = 1) {
    if( $length < 1 ) return false;
    
    $str = array_merge(range('a', 'z'), range('0', '9'), range('A', 'Z"'));
    for ($i = 0; $i < $length; $i++) {
        $r_str .= $str[rand(0, count($str)-1)];
    }
    return $r_str;
}

/* 画像のリサイズ 
 * 返り値 bool
*/
function smart_resize_image(
    $file,
    $width = 0,
    $height = 0,
    $proportional = false,
    $output = 'file',
    $delete_original = true,
    $use_linux_commands = false,
     $quality = 100
) {
        
    if ( $height <= 0 && $width <= 0 ) return false;

    $info = getimagesize($file);
    $image = '';
    $final_width = 0;
    $final_height = 0;
    list($width_old, $height_old) = $info;

    if ($proportional) {
        if ($width == 0) $factor = $height/$height_old;
        elseif ($height == 0) $factor = $width/$width_old;
        else $factor = min( $width / $width_old, $height / $height_old );

        $final_width = round( $width_old * $factor );
        $final_height = round( $height_old * $factor );
    }
    else {
        $final_width = ( $width <= 0 ) ? $width_old : $width;
        $final_height = ( $height <= 0 ) ? $height_old : $height;
    }

    switch ( $info[2] ) {
        case IMAGETYPE_GIF: $image = imagecreatefromgif($file); break;
        case IMAGETYPE_JPEG: $image = imagecreatefromjpeg($file); break;
        case IMAGETYPE_PNG: $image = imagecreatefrompng($file); break;
        default: return false;
    }
    
    $image_resized = imagecreatetruecolor( $final_width, $final_height );
    if ( ($info[2] == IMAGETYPE_GIF) || ($info[2] == IMAGETYPE_PNG) ) {
        $transparency = imagecolortransparent($image);

        if ($transparency >= 0) {
            $transparent_color = imagecolorsforindex($image, $trnprt_indx);
            $transparency = imagecolorallocate($image_resized, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
            imagefill($image_resized, 0, 0, $transparency);
            imagecolortransparent($image_resized, $transparency);
        }
        elseif ($info[2] == IMAGETYPE_PNG) {
            imagealphablending($image_resized, false);
            $color = imagecolorallocatealpha($image_resized, 0, 0, 0, 127);
            imagefill($image_resized, 0, 0, $color);
            imagesavealpha($image_resized, true);
        }
    }
    imagecopyresampled($image_resized, $image, 0, 0, 0, 0, $final_width, $final_height, $width_old, $height_old);
    
    if ( $delete_original ) {
        if ( $use_linux_commands ) exec('rm '.$file);
        else @unlink($file);
    }

    switch ( strtolower($output) ) {
        case 'browser':
            $mime = image_type_to_mime_type($info[2]);
            header("Content-type: $mime");
            $output = NULL;
        break;
        case 'file':
            $output = $file;
        break;
        case 'return':
            return $image_resized;
        break;
        default:
        break;
    }
    
    switch ( $info[2] ) {
        case IMAGETYPE_GIF: imagegif($image_resized, $output); break;
        case IMAGETYPE_JPEG: imagejpeg($image_resized, $output, $quality); break;
        case IMAGETYPE_PNG:
            $quality = 9 - (int)((0.9*$quality)/10.0);
            imagepng($image_resized, $output, $quality);
            break;
        default: return false;
    }

    return true;
}


if ( $_FILES && $_POST['mode'] == 'upload' ) { //画像アップロード時

    $tmpData = array(); //未登録用に初期化

    //拡張子チェック&名前決め
    $tmpData['img']['name'] = randomStr(12); //ファイル名は[不動産ID_フォルダID_ランダム英数字]
    $image_ext = $_FILES['img']['type'];
    if ($image_ext == 'image/jpeg' || $image_ext == 'image/jpg') {
        $tmpData['img']['ext'] = '.jpg';
    } elseif ($image_ext == 'image/png') {
        $tmpData['img']['ext'] = '.png';
    } elseif ($image_ext == 'image/gif') {
        $tmpData['img']['ext'] = '.gif';
    } else {
        echo 'For jpg / png / gif other than, it was not possible to upload the extension of the image.<br /><a href="javascript:void(0);" onClick="history.back();">return</a>';
        exit();
    }

    //フォルダにアップ
    if ($_FILES['img']['size'] > 0) {
        if (!move_uploaded_file($_FILES['img']["tmp_name"], TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext'])){
            echo 'An error occurred while uploading the image.<br /><a href="javascript:void(0);" onClick="history.back();">return</a>';
            exit();
        } else {
            copy(TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext'], IMAGE_PATH . $tmpData['img']['name'] . $tmpData['img']['ext']);//オリジナルサイズの画像をimageフォルダにアップ

            for ($i = 0; $i < count($resizeList); $i++) {
                $sizeName = '-' . $resizeList[$i]['width'] . 'x' . $resizeList[$i]['height'];

                copy(TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext'], TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext']);//リサイズ用画像をtmpフォルダへコピー

                smart_resize_image(
                    TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext'],
                    $width = $resizeList[$i]['width'],
                    $height = $resizeList[$i]['height'],
                    $proportional = false,
                    $output = 'file',
                    $delete_original = false,
                    $use_linux_commands = false,
                    $quality = 100
                );
                copy(TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext'], IMAGE_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext']);//imageフォルダにアップ
                unlink(TMP_PATH . $tmpData['img']['name'] . $sizeName . $tmpData['img']['ext']);
            }

            unlink(TMP_PATH . $tmpData['img']['name'] . $tmpData['img']['ext']); //オリジナルのtmpフォルダ分削除

        }
    }

} //画像処理ここまで

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transtional//EN" "http://www.w3c.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
    <meta charset="utf-8">
</head>
<body>

    <form action="<?=$_SERVER['PHP_SELF'];?>" method="post" enctype="multipart/form-data">
        <input type="file" name="img">
        <input type="submit" name="送信!">
        <input type="hidden" name="mode" value="upload">
    </form>

    <? if( $_POST['mode'] == 'upload' ){ ?>
        <? for($i = 0; $i < count($resizeList); $i++){ ?>
            <?=$resizeList[$i]['title'];?>(width:<?=$resizeList[$i]['width'];?> / height:<?=$resizeList[$i]['height'];?>)<br />
            <img src="./img/<?=$tmpData['img']['name'] . '-' . $resizeList[$i]['width'] . 'x' . $resizeList[$i]['height']  .  $tmpData['img']['ext']?>"><br /><br />
        <? } ?>
        オリジナルサイズ<br />
        <img src="./img/<?=$tmpData['img']['name'] . $tmpData['img']['ext']?>"><br /><br />
    <? } ?>

</body>

 

所感

$resizeListに追加していけばどんどんサムネイルサイズを増やせるはず。

複数ってのが初めてだったので少し手間取った。具体的には1つの画像を縮小⇔拡大を繰り返すと画像が劣化というか変になる。当たり前なんだけど。

なので、リサイズ用に画像を生成してリサイズして元画像は破棄って形をとったけど、なんだかまどろっこしい。

 - PHP

  関連記事

PHPでスマホ(iPhone / Android)に画像をダウンロードさせる方法とダウンロード後の保存場所について

PHPで作ったシステムにスマホ(iPhone / Android)でアクセスし何 ...

PHPで画像アップロード、リサイズ、形式変換(jpg->webp等)はclass.upload.phpが便利

今までPHPで画像関連の処理を行う場合、リサイズの時のみsmart_resize ...

FLASHから受信した画像をPHPで保存し、サムネイルも作る

■参考サイト ・FLASH http://www.ilovex.co.jp/bl ...

CodeIgniter4でフォームからファイルをアップロードし保存する方法

CodeIgniter4.4.4でformから画像等のファイルをアップロードし、 ...

PHPにて指定した画像に対して、繰り返し透かし画像処理する方法

画像素材等のサイトで無料版の画像に対して「sample」等の透かし画像処理を行っ ...