前提・実現したいこと
PHPで元画像の画質を落とさずに画像を縮小し、サムネイルの画像を作成したいです。
発生している問題・エラーメッセージ
該当のソースコード
以下、ソースコードになります。
PHP
1$originalFile = TMP . $userId . DS . $imgName . '.' . $imageExt; // 元画像 2 3list($originalWidth, $originalHeight, $type) = getimagesize($originalFile); 4switch ($type) { 5 case IMAGETYPE_JPEG: 6 $originalImage = imagecreatefromjpeg($originalFile); 7 break; 8 case IMAGETYPE_GIF: 9 $originalImage = imagecreatefromgif($originalFile); 10 break; 11 case IMAGETYPE_PNG: 12 $originalImage = imagecreatefrompng($originalFile); 13 break; 14} 15 16//small画像のサイズを指定 17if (strpos($fileDir, 'comment_files/') === false) { // 縮小のみする場合 18 if ($originalWidth > 300) { 19 $thumbW = 300; 20 $thumbH = $thumbW / $originalWidth * $originalHeight; 21 } else { 22 $thumbW = $originalWidth; 23 $thumbH = $originalHeight; 24 } 25 26 $smallImage = imagecreatetruecolor($thumbW, $thumbH); 27 imagesavealpha($smallImage, true); 28 imagecopyresampled($smallImage, $originalImage, 0, 0, 0, 0, $thumbW, $thumbH, $originalWidth, $originalHeight); 29} else { // 縮小してトリミングする場合 30 $thumbW = 300; 31 $thumbH = 300; 32 33 if ($originalWidth > $originalHeight) { 34 $diffW = $originalHeight; 35 $diffH = $originalHeight; 36 } elseif ($originalWidth < $originalHeight) { 37 $diffW = $originalWidth; 38 $diffH = $originalWidth; 39 } elseif ($originalWidth === $originalHeight) { 40 $diffW = $originalWidth; 41 $diffH = $originalHeight; 42 } 43 44 $smallImage = imagecreatetruecolor($thumbW, $thumbH); 45 imagesavealpha($smallImage, true); 46 imagecopyresampled($smallImage, $originalImage, 0, 0, 0, 0, $thumbW, $thumbH, $diffW, $diffH); 47} 48 49switch ($type) { 50 case IMAGETYPE_JPEG: 51 imagejpeg($smallImage, '_small.' . $imageExt, 100); 52 break; 53 case IMAGETYPE_GIF: 54 imagegif($smallImage, '_small.' . $imageExt); 55 break; 56 case IMAGETYPE_PNG: 57 imagepng($smallImage, '_small.' . $imageExt, 0); 58 break; 59} 60 61// ファイルをアップロード 62if (!$this->formatUploadDataAndUpload( 63 $imgName . '_small.' . $imageExt, 64 $fileName . '_small', 65 $fileDir 66)) { 67 return false; 68}
仕様で縮小してトリミングするパターンと、ただ縮小するパターンとを分けて実装したのですが、どちらで生成した画像もぼやけた画像となってしまいます。
又、調べてimagejpeg、imagepngの第三引数に画像のクオリティを指定できるようだったので100にしてみたのですがぼやけたままでした。ここで指定する前にぼやけてしまう原因があるのかなと思いつつわからないままです。
些細なことでもアドバイスいただけると嬉しく思います。
どうぞよろしくお願いいたします。
追記
皆様ご回答ありがとうございます。
答えになっていなかったらすみません。
最終的にブラウザで横293.91ピクセルの画像表示枠にアップロードした画像を表示予定です。
tabuuさんからのcaseやifの分岐が想定していないコードを実行している可能性もある、とのことで
横300ピクセルの画像で登録してみたところ画質は変わらないようでした。
調べてみて新しくわかったのは、元画像(1098×22000ピクセル)の画像を横300ピクセルに縮小して生成した画像(サムネイル)と元画像を横300ピクセルで指定しブラウザでimageタグで囲い表示し、検証機能で確認した際、縦の長さがそれぞれ6010.93ピクセル(元画像)、6010ピクセル(サムネイル)となっていることに原因があるかもしれないとわかったのですが、round等駆使してみたのですがなぜか小数点が切り捨てられた画像が生成されてしまいます。
↑imagecopyresampled等を通ったときにfloatがintになってしまう過程で小数点が切り捨てられている?
また画像のぼやけ具合ですが
実際に表示される画像を並べました。左側がぼけてしまうサムネイル、右側が縮小していない元画像になります。
追記の追記
ご回答、アドバイスいただきありがとうございます。
以下新しく確認したことになります。
・縦1000ピクセル程度の画像の同様な画像で横300ピクセルに縮小した場合
->上に添付しました画像と変わらないくらいにぼやけておりました。
・ブラウザではなくペイント等のアプリで表示した場合
->上記のソースを通して生成したサムネイル画像で確認いたしましたがぼやけておりました。
・サムネイル画像の縦と横の比率は元画像と同一か
->上記の1回目の追記とにかよりますが、厳密にいえば生成されたサムネイルの縦幅は6010.928961748634であってほしいのですが、小数点が切り捨てられてしまい縦幅6010となってしまっている為、多少の誤差がございます。
縮小しているのだからしょうがないというご意見が多数あるようで、しょうがないと片づけたい気持ちとなんだかすっきりしない気持ちとで悩ましいです。。
質問が拙くて申し訳ないのですが、何かわかることがあれば助言いただけると幸いです。
よろしくお願いいたします。

回答4件
あなたの回答
tips
プレビュー