0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Blenderのシーンでマーカーのあるフレームをレンダリングして台紙画像に並べる

Posted at

アニメーション作品作成で 先に動画コンテのようなラフなシーンを作成して
本制作前に紙のコンテ用紙のようなものに並べたいといった場合もあります。

Blenderはタイムライン上でMキーを押すことで任意の位置にマーカーで目印を浸かられます
image.png
1つのシーン上で このマーカーを打ったフレームの画像をレンダリングして
決まった台紙画像上に並べる処理を作ってみました。

PlaceRenderOnSstoryboard01.py
import bpy
import os
import numpy as np

context = bpy.context
# 台紙画像のファイルパス
base_image_filepath = "//ConteBase01.png"
# 並べる画像の開始位置[横,縦](左上基準)
offset_postion = [230,280]
# カット画像を並べる間隔
tile_height = 525
# 
save_path = "//"

image_base_name = "conte_"
#動画からコンテを作成
def main(context):
    scene = context.scene
    scene.render.use_compositing
    scene.use_nodes = True
    node_tree = scene.node_tree
    # レンダリングの解像度をカットの縦方向と合わせる
    scene.render.resolution_percentage = tile_height*100 //scene.render.resolution_y 
    # 台紙画像の読み込み
    base_img_array = load_as_nparray(base_image_filepath)
    # 台紙画像の大きさの取得
    base_height ,base_width = base_img_array.shape[:2]
    # レンダリング画像をビューアーに出力するノードを作成
    render_rayer_node = node_tree.nodes.new('CompositorNodeRLayers') 
    viewer_node = node_tree.nodes.new('CompositorNodeViewer') 
    node_tree.links.new(render_rayer_node.outputs[0], viewer_node.inputs[0])
    # カットをレンダリングして合成
    page_cuts = (base_height - offset_postion[1]) // tile_height
    page_count = 0
    for i, marker in enumerate (scene.timeline_markers) :
        # マーカーのフレームに移動
        scene.frame_current = marker.frame
        # レンダリング
        bpy.ops.render.render()
        img_array = img_to_nparray(bpy.data.images['Viewer Node'])
        # 台紙画像への割り当て
        if i//page_cuts +1 > page_count:
            if i != 0:
                # 最初の1枚目でなかった場合 前のページの画像を保存
                #numpyarray_to_img(base_img_array,image_name)
                save_nparray_png( save_path, image_name +".png", base_img_array )
                # 台紙画像の読み込み
                base_img_array = load_as_nparray(base_image_filepath)
            page_count += 1
            image_name = "%s_%02d"  % (image_base_name, page_count)
        # 画像は左下基準
        cut_h = base_height -offset_postion[1] -tile_height*(i % page_cuts)
        base_img_array[cut_h -img_array.shape[0] : cut_h, offset_postion[0]: offset_postion[0] +img_array.shape[1] ] = img_array
    # 画像の保存
    #numpyarray_to_img(base_img_array,image_name)
    save_nparray_png( save_path, image_name +".png", base_img_array )
    # 不要なノードの削除
    node_tree.nodes.remove(render_rayer_node)
    node_tree.nodes.remove(viewer_node)

def img_to_nparray(img):
    """rgbaの画像をnumpy arrayに変換"""
    (width,height) = img.size
    channels = img.channels #色数
    #numpy arrayを作成
    pix_array = np.array(img.pixels)
    pix_array = pix_array.reshape( height, width, channels)
    return( pix_array )

def load_as_nparray(f_path):
    """画像の読み込み"""
    abspath = bpy.path.abspath(f_path)
    img = bpy.data.images.load(abspath)
    img_array = img_to_nparray(img)
    #読み込んだ画像オブジェクトの消去
    bpy.data.images.remove(img)
    return(img_array)

def save_nparray_png( save_path, img_name, np_array ):
    """numpy arrayをPNG画像として保存"""
    abspath = bpy.path.abspath(save_path)
    f_path = os.path.join( abspath, img_name )
    (height, width, deps) = np_array.shape
    #画像オブジェクトの作成
    img = bpy.data.images.new(name=img_name, width=width, height=height)
    img.pixels = list( np_array.flatten())
    #保存
    img.save_render(filepath=f_path)
    #画像オブジェクトの消去
    bpy.data.images.remove(img)

main(context)

タイムライン上にマーカーを打った.blendファイルと
ConteBase01.png という名前で下のような画像を同じフォルダに置いて実行してください
ConteBase01.png
設定した間隔で画像を並べた画像ファイルを作成します
(収まらい枚数の場合は次の画像を新たに作成します)
image.png
Blender内で完結させるためにnumpyでの画像合成をしています

尚、Blenderの仕組み上 このスクリプトでは「シーケンサー」を使っている場合には動作しません

台紙にする画像を変更したり 並べる間隔を制御できるようになっています
これをそのまま使うことはないでしょうが 何かの参考になれば幸いです

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?