地上の洞窟

どこにも行かず、液晶と「にらめっこ」し続ける人の物語。

【FFmpeg】とにかく簡単にmp4→gif変換

mp4→gif変換
mp4 → gif変換

※画面は開発中のものです。とか言っとけ定期


前置き

ブログ上でイメージを示したいが、それが動画だったとき。
本来であればvideoタグとか使って動画を埋め込みたいところだが、
はてなブログ君では動画のアップロードが出来なかったりする。

多分TwitterYouTubeに上げた動画を埋め込むのが一番なのだが、
自分はTwitterはROMりたいし、YouTubeになんでもかんでも上げるのはちょっちね。

てなわけで考えられるのが昔ながらの.gifアニメーション
最近は.webpみたいな規格もあるようだが、
はてなブログ君では.webpは取り扱えなかったりする(またかよー!)

というわけで、動画ファイルを.gifに変換する方法を紹介しやす。

準備

動画を.gifに変換する方法は色々ありますが、今回はFFmpegを使用します。

ダウンロード先は色々あるけど、
FFmpeg公式ページ
→ Download
→ Get packages & executable files
Windows EXE Files
Windows builds by BtbN

からでいいと思う。手間だろうからリンク先貼っときます。

github.com

ここのLatest Auto-Build → Assetsから
ffmpeg-master-latest-win64-gpl-shared.zip」をダウンロードして、
.zipファイルなので解凍して、どっか分かる場所に置いとく。

バッチファイル作成

解凍したフォルダの中にある bin\ffmpeg.exe を動かしていくのだが、
コイツを動かすにはコマンドプロンプト(cmd.exe)から
コマンドを入力して動かしてやる必要がある。

ただし、毎回毎回手入力するのも大変だし、場所指定が面倒だったりと色々あるので、
バッチファイル*1を作成して手軽に動かしてあげようという算段。

そして実際に完成したバッチファイルが、こう。

@echo off

set ffmpeg_path="ffmpeg.exe"

if "%~1"=="" (
  echo Please drag and drop target file.
  pause
  exit /b
)

%ffmpeg_path% -i %~1 -filter_complex "fps=24,split[a][b];[a]palettegen[pal];[b][pal]paletteuse=dither=none:diff_mode=rectangle" -y %~n1.gif

pause

このバッチファイルに動画ファイルをドラッグ&ドロップすれば、
同じ場所に同じ名前でgifファイルが生成される。
(既に同名のgifファイルが存在する場合は上書きされるので、注意)

バッチファイルの作り方は普通にテキストファイルを作成して、
拡張子を.batにするだけでおk。あとは↑をコピペするだけ。


バッチファイルの説明

各項を説明していく。

@echo off

これを書いておくと、バッチファイル内で実行されたコマンドが
コマンドプロンプト内に表示されなくなる。

set ffmpeg_path="ffmpeg.exe"

ffmpeg_pathという変数にffmpeg.exeまでのフルパスを代入して使用する。
""内を、各自ダウンロードした ffmpeg.exeまでのフルパス に書き換えて使用してください。

if "%~1"=="" ( ~~~ )

"%~1" というのは、このバッチファイルに対して
ドラッグ&ドロップされたファイルのフルパスを表す。
これがもし空ならば、変換する対象のファイルが無いとみなし処理を終了する。

%ffmpeg_path% -i %~1 ~~~

%ffmpeg_path% -i %~1 -filter_complex "fps=24,split[a][b];[a]palettegen[pal];[b][pal]paletteuse=dither=none:diff_mode=rectangle" -y %~n1.gif

実際にffmpegを実行するための一行。
-filter_complex の後の""内で、.gifアニメのfps*2を設定している。

この値を大きくすれば動きが滑らかになるが、ファイルサイズがクソデカになるので注意。
また、fpsの他にもサイズ指定などができる。

"fps=24,scale=320:-1,split[a][b];[a]palettegen[pal];[b][pal]paletteuse=dither=none:diff_mode=rectangle"

fps=24 の後に scale=320:-1 を追加している。
横幅を320pxに、縦幅は-1、これは指定した横幅320pxに対して、
元の画像の縦横比を崩さないように縦幅を自動計算して、拡大縮小する。

そのあとのごちゃごちゃした項では、動画からパレットを生成して
減色する工程を行ってたりするが、ややこしいのでここでは割愛。

後ろの方についてる -y は、同名のファイルが存在する場合に上書きするオプション。
%~n1 はドラッグ&ドロップされたファイルの名前(フォルダや拡張子を含まない)。


pause

これを書いておくと、バッチファイルの処理が終わった際に、
コマンドプロンプトが自動終了しないようになる。

まとめ

バッチファイルを作成して、ドラッグ&ドロップでmp4をgifに変換する方法でした。
まぁ、それでも面倒っちゃ面倒だよね。特に出力設定変えるのにバッチファイル編集するのが。
なんか動画→gif変換できる簡単なソフトとか作ろうかな?いや、そんな暇は実際ないんだけど。

今回の方法は変換する動画によっては色合いが褪せちゃうことがあります。
その場合は手間ですが、変換する動画に色調補正をかけて、彩度を上げておくとよいです。
(冒頭の画像もそうだったりする)

しかし、.gifファイルは圧縮が悪いのか、
.mp4から比べると画質が悪くなる上に、ファイルサイズが爆増してしまいます。
できることなら動画を直張りした方がいいですね、マジで。


おまけ

動画→アニメーションwebpを出力するコマンド。主に-qscale:v 80の所で画質が変わる

%ffmpeg_path% -i %~1 -vcodec libwebp -filter:v fps=fps=30 -lossless 0 -qscale:v 80 -loop 0 -preset default -an -vsync 0 -compression_level 6 -y %~n1.webp



パレットを使用せず.gifを出力するコマンド。画質は悪いがサイズは小さい

%ffmpeg_path% -i %~1 -r 30 -y %~n1.gif


*1:.batファイル。実行するコマンドを一まとめにして、簡単なプログラムのように扱える

*2:frame per second、一秒あたりのフレーム数

【RGSS3】ポップテキスト

ポップテキスト
名前表示や行き先表示、獲得アイテムの表示などに!

マップ上のキャラクターに対して、指定した文字列を様々な方式で表示します。

表示方法

基本的にはスクリプトを実行して表示します。

「CraftLib」スクリプトを導入していれば、
マップ読み込み時にイベントページの一番上に配置した注釈を読み取り、
イベントを実行せずに表示することもできます。

また、表示方式は、比較的簡単に改造や追加が可能な構造になっています。

ポップテキストの使用方法・改造方法は別ページで詳しく解説しています。


更新履歴 バージョン 内容
2023/09/18 v1.0.0 初版

→スクリプト一覧へ
→「ポップテキストの使用・改造」解説ページへ
→「CraftLib」スクリプト配布ページへ

続きを読む

【RGSS3】CraftLib

「地上の洞窟」が制作した一部のスクリプトの動作に必要な「前提スクリプトです。
(ちなみに機能だけ増やして、機能を使うスクリプトが完成してなかったりする)


更新履歴 バージョン 内容
2023/09/18 v1.0.0 初版

→スクリプト一覧へ

続きを読む

Rubyの正規表現の備忘録

何かと便利だけど何かと忘れがちな正規表現 / Regexpのお話。
書き方も色々あるが、自分が使う書き方だけ書いてく。


基本の使い方

正規表現を使う目的は、
「文字列の中から指定したパターンに一致する部分を抽出する」
ことが大体だと思う。ちょっとややこしい文字列内の検索みたいなもん。

まず、単純に正規表現オブジェクトを作るには、見つけたい文字列を // で囲む。

regexp = /Str/

そしてこれを "String"[regexp] という形式で使う。

"I am String"[/Str/] #=> "Str"


任意文字にマッチ

とにかくなんにでもマッチしてほしければ /.*/ と書く。
しかしそのまま使っても意味は無いので、一定の区間にある
全ての文字にマッチしてくれ的な時にあわせて使う感じ。

"abcdefghijk"[/a.*g/] #=> abcdefg .* が b..f にマッチしている


キャプチャ

"[255, 128, 64]"

「 [ ] の中の数字を抽出するとかどうするの? 」

「え、1項目ずつ取ったりするの?」となりそうだが、そんな必要はない。

string  = "[255, 128, 64]"
if string[/\[(.*),(.*),(.*)\]/]
  r = $1.to_i #=> 255
  g = $2.to_i #=> 128
  b = $3.to_i #=> 64
end

抽出したい部分を ( ) で囲う
マッチするとグローバル変数 $1, $2, $3, ...に、
( )の中の文字列がマッチした順番通りに入っているというわけ。

ちなみに"[ ]"にマッチさせたい場合は
それぞれ \[ \]エスケープを掛けなければならない。

更に、もっと厳密にマッチさせたいなら以下のように書いたりできる。

string  = "[     255  ,  128  , 64     ]"
if string[/\[\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*\]/]
  puts $1 #=> 255
  puts $2 #=> 128
  puts $3 #=> 64
end

空白が余計に入ってても取れるし、数字以外が入ってたら弾いてくれる。
ただ非常にごちゃごちゃして何がしたい正規表現かは見にくい。

要素が2個だったり3個だったり4個だったりと可変長なら、
[ ]内 をまとめて取って、.splitで句切ってあげるのが無難かも。

string  = "[255, 128, 64, 32]"

if string[/\[(.*)\]/]
  $1.split(",").each { |val| p val.to_i } #=> 255 128 64 32
end


文字列の置き換え

正規表現でマッチした文字列をそのまま置き換えることもできる。
一回置き換えるだけならこんな感じ。

text = "12345"
text[/[12345]/] = "n"
puts text #=> n2345

全部置き換えたい場合は .gsub というメソッドを使えば大体いいと思う。

string = "12345"
string.gsub!(/([135])/) { $1.to_i + 1 }
puts string #=> 22446


普通に表示できない文字を分ける

レアケース。キーボードの入力をWin32APIで取って、
それを文字に変換してテキスト入力ができるよ的なことをしようとした時のお話。

一部のキーは入力に対して\e(エスケープ)とか\b(バックスペース)とか、
文字列に追加しても普通に表示できない文字を送ってくる。
こういうのをうまくフィルターすることが出来ないかととりあえず行き着いたのがコレ。

/\p{Other}/

見慣れない書き方だと思う。「Unicode プロパティによる文字クラス指定」らしい。
Otherというクラスを指定することで、普通に表示できない感じの文字を取得できた。
\P{Other}とpを大文字で書けば反転する。つまり普通に表示できる文字が取れる。


擬似的に半角文字、全角文字を分ける

文字の幅を単純計算したいなーと思い、半角全角で分ければいいという時に困ってしまった。
意外と半角・全角を正確に分ける手筈がないのだ。

それもそのはず、Unicodeの文字、特に東アジアの文字?は
「全角半角のすみ分けが曖昧」な文字があり、そもそもすっぱりと分けることはできない模様。

どうしようと行き着いた先に辿り着いた正規表現がこれだった。

/[。-゚[:ascii:]]/

まーた見慣れない正規表現を持ち出してきたよこの人は…(私だ)
この変顔みたいな正規表現

  • ASCII文字(半角英数字)
  • 半角カナ文字
  • 半角記号(日本語)

これを振り分けてくれるようだ。
ちなみに、この。と゚は半角だからね!句点と半濁点の半角だからね!
あと本当にどうでもいいけど、半角半濁点の方はキャレットを合わせたり
deleteで消したりした時の挙動がおかしい。謎。

[:ascii:]はPOSIX文字クラスという何某らしい。文字クラスの中でのみ使用可能。

ちなみにこの記事が大変参考になりました。ありがとうございます。

hush-puppy.hatenadiary.org


パターン作成に便利なサイト

まずは普通に公式のドキュメント。

docs.ruby-lang.org

次に「Rubular」というRubyでの正規表現を簡単に試せるサイト。
英語のサイトなのでちょっとややこしい。自分もどっかで紹介されてたから知った。

rubular.com

あと普通になんでもかんでも試すのに便利なWandboxとか。

wandbox.org


まとめ

正規表現はややこしい!
でも、人の入力とか、そういうのの取り扱いにはとっても便利だから
知っとくに越したことはないんだよね~

(まとめるようなことがなかった)

【RGSS3】メッセージ制御文字追加

メッセージ制御文字追加
制御文字で多彩な表現!

メッセージ表示で新たな制御文字が使えるようになるスクリプトです。
上記のメッセージは、以下のテキストを元に生成されています。

\FB\CRGB[255,0,0]テストテキスト!\CR\FB
ダイスの目は「\FI\#{rand(6)+1}\FI」です。
\CRGB[255,255,255,96]\ORGB[255,255,0,96]だからどうしたってほどでもないけど\CR

追加制御文字

制御文字 説明
\CRGB[R,G,B,A] 文字の色をRGBとアルファ値で指定し変更します。
アルファ値は省略可能。
例: \CRGB[255,0,0]
\ORGB[R,G,B,A] 文字の縁取りの色をRGBとアルファ値で指定し変更します。
アルファ値は省略可能。
例: \ORGB[255,0,0,128]
\CR 文字の色、文字の縁取りの色をデフォルトへリセットします。
\FB 文字の太字状態を切り替えます。
例: \FB強調\FB
\FI 文字の斜体状態を切り替えます。
例: \FI傾く文字\FI
\#{ "script_code" } { } 内の文字をスクリプトとして実行し、
実行結果をテキストとして表示します。
例: \#{rand(6)+1} 1~6のランダムな数字


更新履歴 内容
2023/08/27 初版

→スクリプト一覧へ

続きを読む