こんにちわ。動物大好きエンジニアの”はやぶさ”@Cpp_Learningです。
今日は、このサイトにアフリカオオコノハズクの”くるる”ちゃん@kururu_owl が遊びにきてくれました!
そう言うと普段 お気に入りの場所から ほとんど動かない”くるる”がワルコノ顔で羽を広げ大空へ!
それを見上げる”はやぶさ”。木洩れ日が眩しくて目を細めている。いや木洩れ日以上に輝く何かが眩しい…あれは……なんだ?
ぼんやり考えている ”はやぶさ” をよそに “くるる” が 急降下!!!!
“くるる”が自分に向かってきている!ということに気づくと同時に、眩しかった何かの正体にも気が付いた!!”くるる”の鋭い爪だ!!!
【回想】
まさか、襲う気なのか!?音もなく近づいてくる”くるる”
逃げるか?ダメだ!とても間に合いそうにない…目を一瞬見開いた”はやぶさ”と”くるる”の綺麗な瞳の視線がぶつかり合う!
もうダメだ…ヤラレル…友達だと思っていたのに。。”はやぶさ”は目を強く閉じて倒れこむ。
………
………あれ…?なんともない?
”くるる”の声に反応し、地面に這いつくばってた”はやぶさ”は顔を上げた。
そこにいつもの可愛い顔の”くるる”がいた
安堵と共に思わず本音が漏れる
これをきっかけに ”はやぶさ” と ”くるる” は親友になりましたとさ。めでたしめでたし。
『くるるの野望』エピソード0 ”はやぶさ” と ”くるる”
(完)
Contents
主人公レンズの作り方
とんだ茶番にお付き合い頂き ありがとうございました。”くるる”ちゃんが遊びに来てくれて、ちょっち興奮気味の”はやぶさ”です。
さて、お話の終盤でゲーム画面が出てきました。あれ、私が画像処理で作りました!『主人公レンズ』…と呼ばれるものだそうです。。
作るにあたり、以下の記事で紹介しているソースコード(python)が非常に参考になりました。
”くるる”入り『主人公レンズ』を作るポイント
ベースとなるソースコードについては、上記の参考記事を見ていただくとして、そのベースソースコードの改良ポイントを説明していきます。
素材集め
まずは、素材を集める必要があります。今回は以下のところで商用利用OKのフリー素材を集めました。
”くるる”ちゃんはブログ『くるるの野望』のオーナー”Pon”さんから提供して頂きました。
画像リサイズ
ぱくたそで見つけた背景画像のサイズが大きいため、メッセージウィンドウのサイズ960×160に合わせてリサイズします。
左上の『くるるの野望』ロゴも さりげないサイズにしておきます。
”くるる”ちゃんはリサイズ不要でした。
メッセージウィンドウに合わせて各素材をリサイズする
合成
実はメッセージウィンドウが透けています。薄っすら背景が見えて綺麗ですよね。
この透かしを生かすために以下の順番で背景に画像を重ねます。
「背景」→「くるる+ロゴ」→「メッセージウィンドウ」
素材を重ねる順番に注意!
フォント
今回は”くるる”ちゃんに合わせて『あずきフォント』という可愛らしいフォントを採用しました。
また、メッセージウィンドウに合わせてフォントの色や大きさを調整しました。
目的・メッセージウィンドウに合わせてフォントを調整する
”くるる”入り『主人公レンズ』のソースコード
以上のポイントを踏まえて改造したソースコード(python)を以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
import numpy as np import cv2 from PIL import Image from PIL import ImageDraw from PIL import ImageFont # create text def draw_text(img, text, color): draw = ImageDraw.Draw(img) draw.font = ImageFont.truetype("./azukifont121/azuki.ttf", 30) position = np.array([0, 0]) draw.text(position, text, color) img = Image.new("RGBA", (750, 80)) text = "くるるちゃん可愛い!綺麗な瞳に吸い込まれそうだ!!\nお友達になってください!!!" draw_text(img, text, (255, 255, 255)) img.save('output/text.png') img = Image.new("RGBA", (250, 30)) text = "はやぶさ" draw_text(img, text, (255, 255, 0)) img.save('output/speaker.png') # merge images def merge_images(background, foreground_with_alpha, o_h, o_w): alpha = foreground_with_alpha[:,:,3] alpha = cv2.cvtColor(alpha, cv2.COLOR_GRAY2BGR) # 1 -> 3 alpha = alpha / 255.0 foreground = foreground_with_alpha[:,:,:3] f_h, f_w, _ = foreground.shape b_h, _, _ = background.shape background[b_h-f_h-o_h:b_h-o_h, o_w:f_w+o_w] = (background[b_h-f_h-o_h:b_h-o_h, o_w:f_w+o_w] * (1.0 - alpha)).astype('uint8') background[b_h-f_h-o_h:b_h-o_h, o_w:f_w+o_w] = (background[b_h-f_h-o_h:b_h-o_h, o_w:f_w+o_w] + (foreground * alpha)).astype('uint8') return background # -1 to read alpha channel # foreground: (210, 960, 4) message_box_with_alpha =cv2.imread('samples/message_box2.png', -1) # background: (640, 960, 3) back_img = cv2.imread('samples/kirinosaki.jpg') # hallway # kururu: (250, 300, 3) kururu_img = cv2.imread('samples/kururu.png', -1) # logo: (350, 410, 3) logo_img = cv2.imread('samples/Kururu-LOGOMARK-TATE-350.png', -1) # background resize b_size = (960, 640) resize_back = cv2.resize(back_img, b_size) # merge kururu (300, 250, 3) rb_hight = resize_back.shape[0]*0.8 rb_width = resize_back.shape[1]*0.8 result = merge_images(resize_back, kururu_img, 100, round(rb_width/2)) # logo resize l_hight = logo_img.shape[0]*0.3 l_width = logo_img.shape[1]*0.3 l_size = (round(l_width), round(l_hight)) resize_logo = cv2.resize(logo_img, l_size) # merge logo result = merge_images(result, resize_logo, 510, 20) # result = merge_images(result, logo_img, 0, 0) # merge message_box result = merge_images(result, message_box_with_alpha, 0, 0) # merge text (80, 750, 3) text_with_alpha = cv2.imread('output/text.png', -1) result = merge_images(result, text_with_alpha, 40, 105) # merge speaker (30, 250, 3) speaker_with_alpha = cv2.imread('output/speaker.png', -1) result = merge_images(result, speaker_with_alpha, 145, 50) # resize result for blog r_hight = result.shape[0]*0.7 r_width = result.shape[1]*0.7 b_size = (round(r_width), round(r_hight)) resize_result = cv2.resize(result, b_size) cv2.imwrite("output/result.png", result) cv2.imwrite("output/resize_result.jpg", resize_result) |
おまけ
最後まで読んでいただきありがとうございました。
少し応用して、こんなのも作りました↓ ”くるる”ファン悶絶かな(?)
公開しているソースコードを改良すれば、好きな対象を映した『主人公レンズ』を作れますよ。ちょっち頑張って作ってみませんか?作った画像は友達に自慢しちゃいましょう!
おしまい