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

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

ただいまの
回答率

89.65%

PHPで画像のリサイズ

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,590

PHPのGDで画像のリサイズをしているのですが、リサイズ後の画像が縦に伸びたり横に伸びたりで
うまくいきません。
やりたいこととしましては、プロフィール写真は160*200で、プライベート写真は250*200でリサイズしたいです。
コードはネットで見つけたものを多少修正しています。

以下にコードを記述しますので、どなたかご教授いただければと思います。
よろしくお願いします。

↓呼び出し元

$photo_dir = '../photo/';
$photo_dir1 = '../photo_resize/';

// プロフィール写真
if (file_exists($photo_dir . $line['member_id'] . ".jpg")) {
    if (file_exists($photo_dir1 . $line['member_id'] . ".jpg")) {
        unlink($photo_dir1 . $line['member_id'] . ".jpg");
    }
    $srcPath = $photo_dir . $line['member_id'] . ".jpg";
    $dstPath = $photo_dir1 . $line['member_id'] . ".jpg";
    makeThumbnail($srcPath, $dstPath, 160, 200);
}

// プライベート写真
$photo2_dir = '../photo2/';
$photo2_dir1 = '../photo2_resize/';
if (file_exists($photo2_dir . $line['member_id'] . "_01.jpg")) {
    if (file_exists($photo2_dir1 . $line['member_id'] . "_01.jpg")) {
        unlink($photo2_dir1 . $line['member_id'] . "_01.jpg");
    }
    $srcPath = $photo2_dir . $line['member_id'] . "_01.jpg";
    $dstPath = $photo2_dir1 . $line['member_id'] . "_01.jpg";
    makeThumbnail($srcPath, $dstPath, 250, 200);
}
if (file_exists($photo2_dir . $line['member_id'] . "_02.jpg")) {
    if (file_exists($photo2_dir1 . $line['member_id'] . "_02.jpg")) {
        unlink($photo2_dir1 . $line['member_id'] . "_02.jpg");
    }
    $srcPath = $photo2_dir . $line['member_id'] . "_02.jpg";
    $dstPath = $photo2_dir1 . $line['member_id'] . "_02.jpg";
    makeThumbnail($srcPath, $dstPath, 250, 200);
}
if (file_exists($photo2_dir . $line['member_id'] . "_03.jpg")) {
    if (file_exists($photo2_dir1 . $line['member_id'] . "_03.jpg")) {
        unlink($photo2_dir1 . $line['member_id'] . "_03.jpg");
    }
    $srcPath = $photo2_dir . $line['member_id'] . "_03.jpg";
    $dstPath = $photo2_dir1 . $line['member_id'] . "_03.jpg";
    makeThumbnail($srcPath, $dstPath, 250, 200);
}


↓メソッド

/* ----------------------------------------------------------
 * 画像のサイズを変形して保存する
 * ---------------------------------------------------------- */
function transformImageSize($srcPath, $dstPath, $width, $height)
{
    list($originalWidth, $originalHeight, $type) = getimagesize($srcPath);
    switch ($type) {
        case IMAGETYPE_JPEG:
            $source = imagecreatefromjpeg($srcPath);
            break;
        case IMAGETYPE_PNG:
            $source = imagecreatefrompng($srcPath);
            break;
        case IMAGETYPE_GIF:
            $source = imagecreatefromgif($srcPath);
            break;
        default:
            throw new RuntimeException("サポートしていない画像形式です: $type");
    }

    $canvas = imagecreatetruecolor($width, $height);

    imagecopyresampled($canvas, $source, 0, 0, 0, 0, $width, $height, $originalWidth, $originalHeight);
    imagejpeg($canvas, $dstPath, 100);
    imagedestroy($source);
    imagedestroy($canvas);
}


 /* ----------------------------------------------------------
  * 内接サイズを計算する
  * ---------------------------------------------------------- */
  function getContainSize($width, $height, $containerWidth, $containerHeight)
  {
      if($containerWidth != 160){
          $ratio = $width / $height;
          $containerRatio = $containerWidth / $containerHeight;
          if ($ratio > $containerRatio) {
              return array($containerWidth, intval($containerWidth / $ratio));
          } else {
              return array(intval($containerHeight * $ratio), $containerHeight);
          }
      }else {
          return array($containerWidth, $containerHeight);
      }
      //return array($containerWidth, $containerHeight);

  }

 /* ----------------------------------------------------------
  * 画像のサムネイルを保存する
  * ---------------------------------------------------------- */
function makeThumbnail($srcPath, $dstPath, $maxWidth, $maxHeight)
{
    list($originalWidth, $originalHeight) = getimagesize($srcPath);
    if ($maxWidth > $originalWidth && $maxHeight > $originalHeight) {
        copy($srcPath, $dstPath);
        return;
    }

    list($canvasWidth, $canvasHeight) = getContainSize($originalWidth, $originalHeight, $maxWidth, $maxHeight);

    transformImageSize($srcPath, $dstPath, $canvasWidth, $canvasHeight);
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

DmImageという別なライブラリを使って解決しました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

元の画像と同じ縦横の比(アスペクト比)を維持するためにはそれなりの計算が必要です。
getContainSizeで計算していますが使い方がいまいち合っていないようです。
また、アスペクト比を維持するにしましてもサムネイルの作成(リサイズ)の方法をどうするか
検討する必要があるかと思います。

最終的なサイズは決定している仕様かと思いますのでその前提で。
要はリサイズする結果をどうするかということです。
getContainSizeをCALLしてサイズを取得しているにも関わらず出来上がりのサイズを
$diffWや$diffHにしています。

まずはアップロードの画像サイズとアスペクト比が同じかどうか確認されたほうがよろしいかと思います。
現状では$diffWや$diffH設定が元画像が正方形ではない場合縦横同じサイズでリサイズされますので
伸びたり縮んだりするかと思います。

但し、現状のgetContainSizeですとアスペクト比が異なるアップロード画像では「スキマ」できるかと思います。
「スキマ」のできない「トリミング」も計算で可能です。

何を基準にリサイズ(またはトリミング)するかということです。
これは仕様の話かと思いますのでご確認下さい。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/12 17:47 編集

    メソッドの処理を上記のように変更したのですが、変化はなかったです。

    キャンセル

  • 2017/07/12 19:04

    サムネイルの縦横が160, 200の場合getContainSizeで160, 200 を返しておりますので
    アスペクト比が考慮されていません。
    250, 200の場合うまく行っているのであればgetContainSizeの一部をコメントアウトして
    確認してみて下さい。

    // if($containerWidth != 160){
    ..
    ..
    // }else {
    // return array($containerWidth, $containerHeight);
    // }

    キャンセル

  • 2017/07/13 10:48

    ご回答ありがとうございます。
    別な方法で解決しました。

    キャンセル

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

  • ただいまの回答率 89.65%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる