質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

4回答

5547閲覧

PHPで元画像の画質のまま縮小した画像を作成したい

k_n

総合スコア10

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2019/01/07 11:10

編集2019/01/09 12:03

前提・実現したいこと

PHPで元画像の画質を落とさずに画像を縮小し、サムネイルの画像を作成したいです。

発生している問題・エラーメッセージ

色々なページを参考に(https://qiita.com/suin/items/b01eebc05209dba0eb3e 等)以下のコードを書きましたが、最後にアップロードされる画像が元の画像より多少ぼやけた画像となってしまう原因がわからず困っております。

該当のソースコード

以下、ソースコードになります。

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となってしまっている為、多少の誤差がございます。

縮小しているのだからしょうがないというご意見が多数あるようで、しょうがないと片づけたい気持ちとなんだかすっきりしない気持ちとで悩ましいです。。

質問が拙くて申し訳ないのですが、何かわかることがあれば助言いただけると幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tabuu

2019/01/08 01:12

前提として、画質を落とさずに縮小したいとのことですが、画素を間引くので100%維持するのは難しいと思います。どの程度許容されていますでしょうか。 ぼやける程度にもよりますがどの程度ぼやけるのでしょうか?サンプル画像などありますか? また、caseやifの分岐が想定していないコードを実行している可能性もあるので、例えば横500ピクセルのJPEGに固定して、分岐の無い最小限のコードで実行した場合はどのようになるでしょうか?
yohhoy

2019/01/08 08:00

"横293.91の枠" や "縦の長さがそれぞれ6010.93" の単位系と、どのようにその値を確認したのか(確認手段)を明記したほうがよいです。
k_n

2019/01/08 08:09

アドバイスありがとうございます!不慣れですみません。 修正いたしましたm(__)m
tabuu

2019/01/08 23:26 編集

以下ご確認いただけないでしょうか。 ・1000ピクセル程度の同様な画像を300ピクセルに縮小した場合もぼやけるか? ・ブラウザではなくペイント等のアプリで表示した場合もぼやけるか? ・サムネイル画像の縦と横の比率は元画像と同一か?(追記)
tabuu

2019/01/09 23:48

提示のプログラムのファイル名等を修正して手持ちの画像で実行してみましたが、それほどぼやけているという感じはしませんでした。 実行はCentOSのPHP5.3.3、確認はWindows10のフォトです。 オリジナル:2889x3840 (1.75MB) サムネイル縮小のみ:300x398 (34.6KB) サムネイルトリミング:300x300 (28.4KB) オリジナルの画像が大きいとか、アスペクト比が偏っているとか、縮小率が高いとか、 利用しているライブラリでは無理がきているのかもしれませんね。 他の方がおっしゃっているようにimageMagick等を利用してみてはいかがでしょうか。 ※6000px等であれば利用しているモニタの解像度以上の画像サイズと思われます。 他の方のおっしゃる通り二重三重の縮小の結果、ぼやけるのかもしれません。
guest

回答4

0

300ピクセルに縮小した画像を293.91ピクセルに表示するということは2度縮小していることになるのでそれが原因です。
縮小は1回に留めてください。縮小のたびにぼけます。
また、2回目の縮小の縮小率が小さい(というのか大きいというのか、つまり100%に近い)のも悪い条件です。せめて1回目の縮小を1000ピクセルくらいに大きくしてください。

投稿2019/01/09 01:22

ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

画像処理のライブラリは複数用意されています=こちら
GDの結果が気に入らないならimageMagickを利用するなど別の手段を検討ください

投稿2019/01/08 02:43

yambejp

総合スコア114742

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

画像を縮小しているのですから、画質を下げないというのは不可能です。

imageconvolution関数を使用して画像をシャープにすればぼやけた感じを改善はできます。
http://php.net/manual/ja/function.imageconvolution.php

投稿2019/01/08 02:37

kasa0

総合スコア578

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

皆様、ご回答アドバイスをたくさんいただき本当にありがとうございました。
imageconvolution関数を使用して画像をシャープにしてみたり、imageMagickを使ってみたり、諦めて横幅の指定をもう少し大きくしたりと少しでもよくできるように試行錯誤したいと思います。
ベストアンサー、決めかねるので自決とさせてください。
本当にありがとうございましたm(__)m

投稿2019/01/10 03:48

k_n

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問