GD を使って画像のリサイズを行う場合は imagecopyresampled() を使うのですが、PNG や GIF などで透過情報を保つ場合は工夫が必要です。
そこでアップロードされた画像を指定したサイズに収まるようにリサイズする関数を作ってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | <?php function uploadImage( $tmpName , $dir , $maxWidth , $maxHeight ){ $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo ->file( $tmpName ); if ( $mime == 'image/jpeg' || $mime == 'image/pjpeg' ){ $ext = '.jpg' ; $image1 = imagecreatefromjpeg( $tmpName ); } elseif ( $mime == 'image/png' || $mime == 'image/x-png' ){ $ext = '.png' ; $image1 = imagecreatefrompng( $tmpName ); } elseif ( $mime == 'image/gif' ){ $ext = '.gif' ; $image1 = imagecreatefromgif( $tmpName ); } else { return false; } list( $width1 , $height1 ) = getimagesize ( $tmpName ); if ( $width1 <= $maxWidth && $height1 <= $maxHeight ){ $scale = 1.0; } else { $scale = min( $maxWidth / $width1 , $maxHeight / $height1 ); } $width2 = $width1 * $scale ; $height2 = $height1 * $scale ; $image2 = imagecreatetruecolor( $width2 , $height2 ); if ( $ext == '.gif' ){ $transparent1 = imagecolortransparent( $image1 ); if ( $transparent1 >= 0){ $index = imagecolorsforindex( $image1 , $transparent1 ); $transparent2 = imagecolorallocate( $image2 , $index [ 'red' ], $index [ 'green' ], $index [ 'blue' ]); imagefill( $image2 , 0, 0, $transparent2 ); imagecolortransparent( $image2 , $transparent2 ); } } elseif ( $ext == '.png' ){ imagealphablending( $image2 , false); $transparent = imagecolorallocatealpha( $image2 , 0, 0, 0, 127); imagefill( $image2 , 0, 0, $transparent ); imagesavealpha( $image2 , true); } imagecopyresampled( $image2 , $image1 , 0, 0, 0, 0, $width2 , $height2 , $width1 , $height1 ); if (! file_exists ( $dir )){ mkdir ( $dir , 0777, true); } $filename = sha1(microtime() . $_SERVER [ 'REMOTE_ADDR' ] . $tmpName ) . $ext ; $saveTo = rtrim( $dir , '/\\' ) . '/' . $filename ; if ( $ext == '.jpg' ){ $quality = 80; imagejpeg( $image2 , $saveTo , $quality ); } else if ( $ext == '.png' ){ imagepng( $image2 , $saveTo ); } else if ( $ext == '.gif' ){ imagegif( $image2 , $saveTo ); } imagedestroy( $image1 ); imagedestroy( $image2 ); return $saveTo ; } if ( $_SERVER [ "REQUEST_METHOD" ] === 'POST' && ! empty ( $_FILES [ 'image' ][ 'tmp_name' ])) { $now = new DateTime(); $maxWidth = 300; // 最大幅 $maxHeight = 300; // 最大高さ // 一時ファイルの場所 $tmpName = $_FILES [ 'image' ][ 'tmp_name' ]; // 保存先のディレクトリ $dir = __DIR__ . '/files/' . $now ->format( 'Y/m/d' ); $path = uploadImage( $tmpName , $dir , $maxWidth , $maxHeight ); var_dump( $path ); exit ; } ?> <!DOCTYPE html> <html> <head> <meta charset= "utf-8" > <title>image</title> </head> <body> <form method= "POST" enctype= "multipart/form-data" > <input type= "file" name= "image" > <input type= "submit" value= "submit" > </form> </body> </html> |
リサイズに成功すると保存先のファイルパスを返します。失敗した場合は false を返します。
拡張子偽装の可能性を考慮して finfo で MIME type を調べるようにしています。
Similar Posts:
- [PHP]マスク画像で写真を好きな形に切り抜く(クリッピングマスク)
- [PHP]似た画像を検索して近い順番に並べる(類似画像検索)
- [PHP]HSV(HSB)色空間を比較して似た色合いの画像を検索する
- [PHP]似た色合いの画像をRGB値をもとに探す
- [PHP]画像を上下反転、左右反転する(垂直・水平方向の鏡像)
- [PHP]円グラフを表示する(GD)
- [PHP]複数の画像をランダムに敷き詰めて一枚の画像に合成
- [JS]画像ファイルアップロード前にプレビューを表示する