人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

phpでアニメーションGIFを作りたいのですが、何を使っていますか?

目的はモバゲーのアバターのように、静止画像とアニメーションを組み合わせたようなものです。
静止画像はpngで用意して、それを重ね、レイヤーの一つとしてアニメーションgifも入れることができて、
最終的に出力されるgifもアニメーションgifに成っているようなイメージです。

また、imagegifを使って静止画像を作っていますが、画質が悪いです。合わせて解決できると嬉しいです

●質問者: dingding
●カテゴリ:インターネット ウェブ制作
✍キーワード:GIF PHP PNG アニメーション アニメーションGIF
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● smallzhu
●0ポイント (はてなにより削除しました)
2 ● Numeric
●80ポイント

?GIFアニメーションの作成

ImageMagickとPECL::ImagickでアニメーションGIFを合成する: Kwappa開発室

ここにちょうどいいサンプルコードがありましたので紹介します。


■GifCompositeクラス

<?php
class GifComposite
{
 // imagick objects
 private $imgs ; // 合成対象(array)
 private $result ; // 合成結果
 private $anim_delay ; // アニメーションディレイ

 // 合成のベースとなる透明画像
 const TRANS_IMG = "img/blank.gif" ;

 /**
 * コンストラクタ
 * @param array &$img_files 画像ファイルのパス配列
 * @param integer $anim_delay 1コマの時間(msec)
 */
 public function __construct(&$img_files, $anim_delay = 20)
 {
 foreach ($img_files as $img_file)
 {
 $this->imgs[] = new Imagick($img_file) ;
 }
 $this->result = new Imagick(self::TRANS_IMG) ;
 $this->anim_delay = $anim_delay ;
 }

 /**
 * 合成
 */
 public function composite()
 {
 //----------------------------------------------------------------------
 // 最大フレーム数を算出
 //----------------------------------------------------------------------
 $max_frames = 0 ;
 foreach ($this->imgs as &$img)
 {
 // 枚数をチェックして最大数を控える
 $num = $img->getNumberImages() ;
 if ($num > $max_frames) $max_frames = $num ;
 unset($img) ;
 }
 if ($max_frames <= 0) return false ;

 //----------------------------------------------------------------------
 // アニメーションアイテムを読み込んでいなければ単純に合成して終了
 //----------------------------------------------------------------------
 if ($max_frames == 1)
 {
 // 透明画像に全部かぶせて終了
 foreach ($this->imgs as $key => &$img)
 {
 $this->result->compositeImage($img, imagick::COMPOSITE_OVER, 0, 0) ;
 }

 $this->result->writeImages("result.gif", true) ;
 return true ;
 }

 //----------------------------------------------------------------------
 // アニメーションアイテムの合成
 //----------------------------------------------------------------------
 $comp_tmp = $this->result->clone() ; // 透明画像の控えを取っておく
 // アニメーションのコマ数ループ
 for ($i = 0 ; $i < $max_frames ; $i ++)
 {
 // 2コマ目以降:積み込み先画像は透明画像のコピー
 if ($i > 0)
 {
 $target = $comp_tmp->clone() ;
 }
 // 1コマ目:積み込み先画像は結果として使う予定の透明画像
 else
 {
 $target = &$this->result ; // 使用後かならずunsetしないと悲惨
 }
 // 読み込み済みファイルをループ
 foreach ($this->imgs as $key => &$img)
 {
 $count = $img->getNumberImages() ; // 画像のコマ数
 // アニメーションアイテムならコマを指定
 if ($count > 1)
 {
 $index = $i % $max_frames ;
 }
 // 通常アイテムは1コマ目
 else
 {
 $index = 0 ;
 }
 // コマ数を指定して$this->resultにかぶせる
 $img->setImageIndex($index) ;
 $target->compositeImage($img, imagick::COMPOSITE_OVER, $offset_x, $offset_y) ;
 }
 $target->setImageDelay($this->anim_delay) ; // アニメーションディレイの設定
 // 最初のコマ
 if ($i == 0)
 {
 $target->setImageIterations($loop_count) ; // アニメーションループの設定
 }
 // それ以降
 else
 {
 $this->result->addImage($target) ; // 結果画像に積む
 $target->destroy() ; // 後片付け
 }
 unset($target) ; // 変数の解放(参照入れてるので重要)
 }
 return true ;

 }

 /**
 * 合成結果を保存
 * @param string $save_name 保存先のパス
 */
 public function save($save_name)
 {
 $frames = $this->result->getNumberImages() ;

 // アニメーションしなければ普通に書いて終了
 if ($frames == 1)
 {
 return $this->result->writeImage($save_name) ;
 }

 // アニメーションするなら最適化
 // 結果画像を書き出す
 $this->result->writeImages("{$save_name}.MIFF", true) ;
 // Quantizeが使えないので保存ファイルをconvert +mapに通す
 exec("convert {$save_name}.MIFF -layers OptimizeTransparency +map {$save_name}", $ret, $result) ;
 // エラーチェックは省略
 return true ;
 }
}
?>

■動作サンプル

<?php
// 合成画像の配列
$img_files = array(
 "img/sara_yamaguchi.gif",
 "img/devlish_heart.gif",
) ;

$gifComposite = new GifComposite($img_files) ;
$gifComposite->composite() ;
$gifComposite->save("result.gif") ;
?>

?静止画(GIF)の画質について

新規画像作成時に「imagecreate()」を使用していませんか?

「imagecreatetruecolor()」を使用することで画質は改善するはずです。

それでも画質が悪いと感じるなら、それはきっとGIFには向かない画像なのでしょう。

◎質問者からの返答

大変詳しいコードをいただいてとても参考になります。ありがとうございます。

imagecreatetruecolorを使っていますが、期待した画質ではないですね。

ImageMagickを試してみます。


3 ● simoke123
●0ポイント (はてなにより削除しました)
関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ