Blender を使った Web サービス「プロ生ちゃんTシャツジェネレーター」を作ったよ
暮井 慧: こんにちは! 私、暮井 慧。今回は、3DCG アニメーション作成の統合環境アプリ Blender のコマンドラインレンダリングを使って、Web サービスを作ってみたよ!。これは、Blender Advent Calendar 2016 12日目と、プロ生ちゃん Advent Calendar 2016 12日目の投稿だよ。
Web サービス構想
私の 3D モデルデータは、Blender 製で、Tシャツモデルはテクスチャ画像を編集して、簡単にTシャツをデザインできるようになってるんだよね。
というわけで、ユーザーがアップロードした画像をテクスチャ画像に合成して、Blender のレンダリング結果を返す Web サービスを作ってみるよ。
Blender のインストール
Blenderのインストール(Linux) < インストール | Blender入門(2.7版) を参考に Linux サーバーにインストール!
私の環境だと yum install blender でインストールできなかったので、公式バイナリを展開してインストール、必要なライブラリを yum コマンドでインストールしたよ。
コマンドラインでレンダリング
Blender の GUI を起動せずにレンダリングする方法は、Doc:JA/2.6/Manual/Render/Command Line - BlenderWiki をチェック!
静止画のレンダリングは、次のようになるよ。
blender -b pronama-chan.blend -o //out# -F PNG -x 1 -f 1
- -b: GUI を起動せず実行
- -o: 出力パスとファイル名 // は blend ファイルからの相対位置指定。# の部分にフレーム数が入る。
- -F: 画像形式指定
- -x 1: 出力ファイル名に拡張子を付ける
- -f 1: 1フレーム目をレンダリング
Web サービス化!
Blender のインストールと、コマンドラインでの実行方法はわかったから、後はユーザーがアップロードした画像をテクスチャ画像に合成して、Blender を実行、出力ファイルを結果として返すって感じのコードを書いて Web サービスに仕上げよう!
PHP 部分。
<?php | |
$result = ""; | |
if (isset($_FILES['file']['error']) && is_int($_FILES['file']['error'])) { | |
$file = $_FILES['file']['tmp_name']; | |
$dir = sys_get_temp_dir(); | |
$id = uniqid(); | |
exec("cp -R /home/pronamajp/blendfiles/ $dir/$id"); // Blender データファイル一式を一時フォルダーへコピー | |
createTshirtTex($file, "$dir/$id/Tsyatu.png"); // アップロードされた画像をTシャツテクスチャ画像へ合成 | |
exec("/usr/local/blender/blender -b $dir/$id/pronama-chan.blend -o //out# -F PNG -x 1 -f 1"); // レンダリング実行 | |
exec("mv $dir/$id/out1.png /home/pronamajp/DocumentRoot/blendertest/out/$id.png"); // 出力画像を移動 | |
exec("rm -rf $dir/$id"); // 一時フォルダーを削除 | |
$result = "http://pronama.jp/blendertest/out/$id.png"; // 出力画像の URL | |
} | |
// Tシャツテクスチャ画像への合成 | |
function createTshirtTex($filename, $out_filename) | |
{ | |
// Tシャツのテクスチャ画像 | |
$tex_filename = "/home/pronamajp/DocumentRoot/blendertest/Tsyatu.png"; | |
// Tシャツのデザイン位置・サイズ | |
$offset_x = 164; | |
$offset_y = 516; | |
$width = 220; | |
$height = 320; | |
// アップロード画像をリサイズ | |
$resized_im = resizeImage($filename, $width, $height); | |
$w = imagesx($resized_im); | |
$h = imagesy($resized_im); | |
// テクスチャ画像にアップロード画像を描画して指定先に保存 | |
$tex_im = imagecreatefrompng($tex_filename); | |
imagecopy($tex_im, $resized_im, $offset_x + floor(($width – $w) / 2), $offset_y + floor(($height – $h) / 2), 0, 0, $w, $h); | |
imagepng($tex_im, $out_filename); | |
imagedestroy($tex_im); | |
imagedestroy($resized_im); | |
} | |
// 指定サイズに画像をリサイズ | |
function resizeImage($filename, $max_width, $max_height) | |
{ | |
list($orig_width, $orig_height) = getimagesize($filename); | |
$width = $orig_width; | |
$height = $orig_height; | |
if ($height > $max_height) { | |
// taller | |
$width = ($max_height / $height) * $width; | |
$height = $max_height; | |
} | |
if ($width > $max_width) { | |
// wider | |
$height = ($max_width / $width) * $height; | |
$width = $max_width; | |
} | |
$image_p = imagecreatetruecolor($width, $height); | |
imagealphablending($image_p, false); | |
imagesavealpha($image_p, true); | |
$image = imagecreatefromstring(file_get_contents($filename)); | |
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $orig_width, $orig_height); | |
imagedestroy($image); | |
return $image_p; | |
} | |
?> |
パスはフェイクで、実際に動いているコードは、不正リクエストチェックも入っているよ。ファイルアップロードの例外処理はこれぐらいしないと気が済まない - Qiita を参考にしたよ。
HTML 部分。
<h1>プロ生ちゃんTシャツジェネレーター</h1> | |
<form action="./" method="POST" enctype="multipart/form-data"> | |
<input type="file" name="file"> | |
<input type="submit" value="画像ファイルをアップロードする"> | |
</form> | |
<?php | |
if ($result) { | |
echo '<img src="' . $result .'" />'; | |
} | |
?> |
完成!
サイトのデザインを整えたら、プロ生ちゃんTシャツジェネレーター の完成だよ! いろいろな画像で試してみてね。
Blender ファイルダウンロード
3D モデルのファイルも公開するよ。使うときは、利用ガイドライン を守ってね。
アキバで見かけた萌えキャラコンテスト(12/17 〆切)
AKIBA PC Hotline! の 「アキバで見かけた萌えキャラコンテスト」読者投票 にエントリーされているから、投票して応援してね。
最新記事 by kei (全て見る)
- 自作PC・MOD PCコンテスト作品「しろたんPC」 - 2021/01/22
- 自作PC・MOD PCコンテスト作品「X68030 PROnama-68K」 - 2021/01/22
- 自作PC・MOD PCコンテスト作品「モンスターすぺっくマシン Ver. 2.03(ポチ子仕様)」 - 2021/01/12