imagemagickをphpでexecコマンドで利用しています。


不定形の投稿された画像からサムネイルを生成したいと思います。

サムネイルは投稿された画像の中心がサムネイルの中心となり且つ100*100サイズとなるようにしたいと思いますが、どのようにすれば良いでしょうか?

execコマンドを教えていただければと思います。よろしくお願いいたします。

回答の条件
  • 1人2回まで
  • 登録:2009/01/21 14:12:38
  • 終了:2009/01/23 15:04:01

ベストアンサー

id:tail_furry No.1

敷守ほむら回答回数74ベストアンサー獲得回数72009/01/21 15:31:53

ポイント60pt

imagemagickを使わなくても、短い辺の長さにあわせた画像を作成し、その後、PHPで100×100の画像を作って、それに当てはめればできます…。

// 画像の幅と高さを取得します(画像ファイルのパスを$filepathとします)

list($width, $height) = getimagesize($filepath);

// 画像を取得します(仮にjpegだとします)

$src = imagecreatefromjpeg($filepath);


// 短い辺の長さを100にするように、縮小した後の縦と横の長さを計算します

if ($width > $height) {

// 横長

$width_thumb = ceil($width * 100 / $height);

$height_thumb = 100;

}

else {

// 縦長

$width_thumb = 100;

$height_thumb = ceil($height * 100 / $width);

}


// 100pixel×100pixelの空の新規画像を作成します

$dst = imagecreatetruecolor(100, 100);

// 作った画像に用意した画像をコピー、伸縮します。

imagecopyresampled($dst, $src, ceil((100 - $width_thumb) / 2), ceil((100 - $height_thumb) / 2), 0, 0, $width_thumbs, $height_thumbs, $width, $height);


どうしてもimagemagickを使いたいのであれば、100pixel×100pixelの空の新規画像を作成する前にimagemagickで縮小した画像を作ってから当てはめる形になるかと思います。

参照:kiyoeri - ImageMagickコマンド集

(imagemagickのバージョンによって使えないコマンドがあるので注意)

// imagemagickを使う

// (仮に/usr/bin/ にimagemagickの実行ファイルがあると仮定)

// $tmpfilepathはテンポラリーファイルのパスを指定

exec('/usr/bin/convert -geometry '.$width_thumb.'x'.$height_height.' "'.$filepath.'" "'.$tmpfilepath.'"');


または、こちらのページの-resizeというコマンドを使って

ImageMagickで簡単に画像処理 - PHPプロ!TIPS+

// imagemagickを使う

// (仮に/usr/bin/ にimagemagickの実行ファイルがあると仮定)

// $tmpfilepathはテンポラリーファイルのパスを指定

exec('/usr/bin/convert "'.$filepath.'" -resize '.$width_thumb.'x'.$height_height.' "'.$tmpfilepath.'"');


これによってimagecopyresampledの指定が変わってきます。たぶんこうだと思うのですが、間違ってたらごめんなさい。

// 作った画像に用意した画像をコピー、伸縮します。

imagecopyresampled($dst, $tmpfilepath, ceil((100 - $width_thumb) / 2), ceil((100 - $height_thumb) / 2), 0, 0, $width_thumbs, $height_thumbs, $width_thumbs, $height_thumbs);

id:ruijio

詳細な回答ありがとうございます。

exec('/usr/bin/convert -geometry '.$width_thumb.'x'.$height_height.' "'.$filepath.'" "'.$tmpfilepath.'"');

を試してみましたがうまくいきませんでした。

$filepathと$tmpfilepathを逆にしたら、このコマンドについてはOKでした!

ただ、最後にphpの関数を使うということですよね?

折角なので、画像生成に関してはすべてimagemgickで行いたいと思います。

最初のgetimagesize($filepath);は初めて知りました。これをうまく使えば座標の計算ができそうですね。

また試してみたいと思います。

ありがとうございました。

2009/01/23 12:56:57
  • id:tail_furry
    すみません、回答してから気づいたのですが、getimagesize, imagecreatefromjpeg, imagecreatetruecolor, imagecopyresampled の関数は、GDモジュールが必要でした。
    もしGDモジュールが使えない環境でしたら申し訳ないです・・・
  • id:ruijio
    解決しました。
    処理の流れとしては、
    1・投稿画像の縦横を取得する。
    2・縦長か横長か判別
    3・(横長の場合)。縦横を縦幅でcrop。600*400なら400*400。クロップピングポイントは縦は0、横は以下の計算式
     (横幅 / 2) - (縦幅 / 2)
    3・exec convert -crop を一度実行し、正方形且つ、画像の中心をくりぬけます。
    4・exec convert -quality 90 -resize 100x100\> で目的100*100のサムネイルが完成。
    方形にトリミング


    // 投稿された画像の幅と縦を取得
    list($w , $h) = getimagesize($tmpfile);

    // 縦長か横長に応じて処理を変える

    if($w >= $h){
    // 横長の場合
    $sq = $h; // 仮画像の正方形の辺は小さいほうになる。
    $rspW = intval($w / 2) - intval($h / 2); // リサイズポイント:Width
    $rspH = 0; // リサイズポイント:Height
    } else {
    // 縦長の場合
    $sq = $w; // 仮画像の正方形の辺は小さいほうになる。
    $rspH = intval($h / 2) - intval($w / 2); // リサイズポイント:Height
    $rspW = 0; // リサイズポイント:Width
    }

    $reH = intval($h / 2 ) - 50 ;
    $reW = intval($w / 2 ) - 50 ;

    exec("convert -crop $sq"."x"."$sq+$rspW+$rspH $tmpfile $outputpath") ; // ここで正方形にトリミング

    // すぐに次の作業に行くと画像ができてるかどうか不安なので時間稼ぎしてみる。
    for($i = 0 ; $i < 500 ;$i++){$a = 1;}
    exec("convert -quality 90 -resize 100x100\> $outputpath $outputpath2") ; // 前に作った正方形の画像を目的の100*100


    と言う感じです。

    tail_furryさん、ありがとうございました。

  • id:tail_furry
    -cropは使ったことありませんでしたが、なるほど、こんな風に使えるのですね。
    こちらこそ勉強になりました。どうもありがとうございます。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません