こんにちは!
駆け出しエンジニアとしてプログラミングを頑張ってるよー
とにかく好奇心旺盛なのだ!
今回はProcessingで画像処理プログラミングに挑戦するよー♪
Contents
プロモーションビデオを作成したい!
とか考えてたら…
Processingは教育用途からアート、実用まで幅広い可能性を持ってるプログラム言語だと思う。自分はたまに使うくらいだけど、ずっと使い続けて発信している人たちは、尊敬の念しかない
— からあげ (@karaage0703) February 3, 2019
Processingはイイぞ~というツイートを見つけた!
気になったので少し調べてみたら、Processingで以下ようなデジタルアートが作れるみたい!
というわけで、Processingで LINEスタンプ のプロモーションビデオ作るよー
環境構築
環境構築10分で終わりました!
公式サイト”Download Processing”から自分が使用しているOSを選択してダウンロードします。
今回はWindows(64-bit)をダウンロードしました。
ZIPファイルを解凍して、processing.exeをクリックするとIDE(スケッチブック)が起動します。(Arduinoに似てる…)
3ステップで簡単にプログラミングできました!
- 赤枠部分にソースコードを書く
- 緑枠の実行ボタン クリック
- すぐに作品が表示されます
↑のソースコードは「描画した★をマウスで動かす」プログラムです。
Processing入門
Processing公式サイトにリファレンス/チュートリアル/Exampleまで丁寧な説明がありました。
幾何学模様などはコピペですぐに描画できます!
Processingのプログラミング作法
Processingには2つの重要な関数があります。
setup()はプログラミング起動時に一度だけ実行されます。そのため、Windowサイズなどの初期設定はsetup()に書きます。
draw()はsetup()の後に繰り返し実行されます。他言語のwhile/for/loopのようなものだと考えて良いよー(*・ω・)ノ♪
Processingでプロモーションビデオを作る
Processing公式サイトのコードを切ったり張ったりして、プロモーションビデオを作ったよー!
ソースコード公開
プロモーションビデオのソースコードは以下の通りです。
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
// image PImage img_kururu; PImage img_logo; PImage img_see; PImage img_forest; PImage img_line; // for music import ddf.minim.*; Minim minim; AudioPlayer player; // load image void setup(){ size(1280, 720); img_kururu = loadImage("img/kururu_fly2.png"); img_logo = loadImage("img/Kururu-LOGOMARK-YOKO-500pix.png"); img_see = loadImage("img/see_in_hagi.jpg"); img_forest = loadImage("img/forest.jpg"); img_line = loadImage("img/kururu_LINE.jpg"); background(0); minim = new Minim(this); player = minim.loadFile("music/game_maoudamashii_4_field11.mp3"); player.play(); line(); } // initial value int rrx = 0, rry = 0; int rux = 0, ruy = height; int lx = 0, ly = 0; int rr2x = 0, rr2y = 0; int rbx=0, rby = 0; float cr = 0; float c2r = 0; int kx = 0, ky = 0; float hx, hy; float kx2, ky2; float theta = 0, R = 10; int kx3=width/2, ky3=height/2; int rdx = 0, rdy = 0; int flag = 0; // Time float time = 0; // ===== scene (like layers) ↓ ====== void bubble(){ for(int i = 0; i < 20; i++){ float x = random(width); float y = random(height); fill(0); noStroke(); ellipse(x, y, 50, 50); } } void rect_right(){ rry = height/2; fill(255); rect(0, 0, rrx, rry); rrx += 7; } void logo(){ ly = height/2-200; if (lx < width/2-250){ image(img_logo, lx, ly); lx += 3; }else{ lx = width/2-250; image(img_logo, lx, ly); } } void rect_up(){ fill(255); rect(0, height, width, ruy); ruy -= 5; } void Circle(){ fill(0); ellipse(width/2, height/2, cr, cr); cr += 7; } void Circle2(){ fill(255); ellipse(width/2, height/2, c2r, c2r); c2r += 7; } void rect_right2(){ rr2x = width; fill(0); rect(0, 0, rr2x, rr2y); rr2y += 5; } void rect_bigger(){ fill(255); rect(0, 0, rbx, rby); rbx += 7; rby += 7; } void kururu(){ ky = height/2-200; background(255); image(img_kururu, kx, ky); if(kx < width/2-180){ kx += 5; } } void Heart(){ int R = 20; strokeWeight(2); stroke(200, 0, 0); fill(255, 150, 150); strokeJoin(ROUND); pushMatrix(); translate(width/2, height/2); beginShape(); for (int theta = 0; theta < 360; theta++) { hx = R * (16 * sin(radians(theta)) * sin(radians(theta)) * sin(radians(theta))); hy = (-1) * R * (13 * cos(radians(theta)) - 5 * cos(radians(2 * theta)) - 2 * cos(radians(3 * theta)) - cos(radians(4 * theta))); vertex(hx, hy); } endShape(CLOSE); popMatrix(); } void kururu2(){ image(img_see, 0, 0); theta += 5; R += 0.5; kx2 = R * cos(radians(theta)) + width/2 - 180; ky2 = R * sin(radians(theta)) + height/2 - 200; image(img_kururu, kx2, ky2); } void bubble2(){ for(int i = 0; i < 20; i++){ float x = random(width); float y = random(height); color c = img_forest.get(int(x),int(y)); fill(c,25); noStroke(); ellipse(x, y, 80, 80); } } void kururu3(){ image(img_forest, 0, 0); image(img_kururu, kx3+200, ky3); kx3 += 2; ky3 -= 2; } void rect_down(){ rdx = width; fill(0); rect(0, 0, rdx, rdy); rdy += 3; } void end(){ fill(255); textSize(100); text("END", width/2-100, height/2); music_stop(); } void line(){ textSize(100); text("NOW ON SALE", width/2-300, height/2-260); image(img_line, width/2-250, height/2-250); // super.stop(); } // ===== scene (like layers) ↑ ====== void music_stop(){ player.close(); minim.stop(); // super.stop(); } void draw(){ if(2<=time && time<=5) bubble(); if(5<=time && time<=25) rect_right(); if(5<=time && time<=25) logo(); if(20<=time && time<=40) rect_up(); if(35<=time && time<=70) Circle(); if(50<=time && time<=80) Circle2(); if(73<=time && time<=90) rect_right2(); if(80<=time && time<=100) rect_bigger(); if(100<=time && time<=115) kururu(); if(115<=time && time<=120) Heart(); if(120<=time && time<=145) kururu2(); if(145<=time && time<=200) bubble2(); if(200<=time && time<=220) kururu3(); if(220<=time && time<=260) rect_down(); if(260<=time && time<=270) end(); if(270<=time) line(); time += 0.1; } |
ソースコードの解説❶ -拡張性-
円/四角形/フクロウの図などを描画する関数を作成し、それらの関数をプロモーションの各シーンだと考えます。
あとは各シーンのタイミングを考えて順番に実行する感じだよ↓
↑のように円や四角形を連続で描画したり…
↑のように同時に円や四角形を描画したり…
以下のコードを層のように重ねるだけで、簡単にプロモーションビデオを作れます。
if(start_time && end_time) myfunc();
この書き方だと、シーンの長さ・挿入・追加が簡単に修正できるので、拡張性抜群でした!
拡張性を意識したソースコードに仕上げました!(フレームワークというと少し大袈裟だけど…そんなイメージで作ったよ!この型を使えば、簡単にオリジナル動画が作れるよー)
ソースコードの解説❷ -図形のサイズ変更-
ソースコードの骨格(フレーム)が決まったので、次は関数(シーン)を作っていくよー
プロモーションビデオで円が大きくなったり、四角形が伸びたりする演出がありました!
実は”そう見えていただけ”で実際には図形を少しずつ変形させながら、上書きしていました。
例えば、↑のソースコードをdraw()に書けば、任意の位置(座標 x, y)に 白の四角形 を描画することができます。
draw()は繰り返し実行されるので、↑の”rx += 7”や”ry += 7”などのインクリメントするコードを書いておけば、 白の四角形 のサイズを少しずつ大きくして上書き描画できます。
つまり、緑破線の 白の四角形 にひと回り大きい 白の四角形 を上書きして、さらにひと回り大きい 白の四角形 を上書き…
…というのをdraw()で繰り返し実行して図形が拡大するような演出をしていました。
四角形などの図形を少しづつ変形させて上書きすることで、図形が伸びたり・大きくなる演出ができます。
ソースコードの解説➌ -図の移動(基礎)-
次は図の移動について解説します。
基本的には、解説❷で説明した図の上書きと同じです。
しかし、単純に上書きするだけだと…
↑のように残像が残ってしまいます。(これはこれでカッコイイかも!)
そのため、移動させたい図だけでなく、背景(bacgroung)も上書きして画面をクリアにしてから少し移動させた図を描画します。
この処理をdraw()で繰り返し実行することで、図が動いているような演出ができます!
背景を更新して画面をクリアにしてから、図を少し移動させると、図が動くような演出ができます。
ソースコードの解説❹ -図の移動(応用)-
解説➌の応用について解説します。
滑らかな曲線は、sinθ(サイン)・cosθ(コサイン)で表現できるよ!
フクロウが螺旋を描いて飛ぶ演出には「アルキメデスの螺旋」の数式を使いました。
sinθ・cosθは様々な所で使われています。例えば、今回のように滑らかな曲線を描いたり、モノを滑らかに移動させるのにsinθ・cosθが使えます。
Processingでオリジナルビデオを作ろう!
本記事のソースコードを改良すれば、簡単にオリジナルビデオを作れるよ!
例えば、ソースコード冒頭部分でプロモーションビデオで使用する画像や音楽を設定しています↓
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 |
// image PImage img_kururu; PImage img_logo; PImage img_see; PImage img_forest; PImage img_line; // for music import ddf.minim.*; Minim minim; AudioPlayer player; // load image void setup(){ size(1280, 720); img_kururu = loadImage("img/kururu_fly2.png"); img_logo = loadImage("img/Kururu-LOGOMARK-YOKO-500pix.png"); img_see = loadImage("img/see_in_hagi.jpg"); img_forest = loadImage("img/forest.jpg"); img_line = loadImage("img/kururu_LINE.jpg"); background(0); minim = new Minim(this); player = minim.loadFile("music/game_maoudamashii_4_field11.mp3"); player.play(); line(); } |
画像一覧は以下の通り。
- img_kururu:空を飛ぶ”くるる”のイラスト
- img_log:「くるるの野望」ロゴ(ビデオの始め頃に登場)
- img_see:背景1(海の画像)
- img_forest :背景2(森の画像)
- img_line:LINEスタップのイラスト(ビデオの最初と最後に登場)
また、音楽についてはフリー音楽BGM素材サイト魔王魂のゲーム向けBGM素材を使いました。
あとは、解説❶で説明した”シーン(関数)”のタイミングを変更したり、オリジナルの”シーン(関数)”を自作するのも面白いと思うよ!
分かるところから少しずつ改良していき、自分の”出来ること”を増やしてね!
まとめ
プロモーションビデオを作りたい!と思った次の日から…
本記事を読んで『プログラミンたーのしーい!もっと色んな数式を知りたーい!』という人が現れたら、すごく嬉しいなぁ
おまけ -本ブログのサポートについて-
- 拡張性を考慮したソースコード!
- sinθ・cosθの数式をポップな感じで紹介!
プログラミングが義務教育になるらしいけど、少しでも楽しくプログラミングを勉強してほしいと想って本記事を書いたよー
本ブログのサポート方法
本チュートリアルが参考になり、”くるる”ちゃんに投げ銭(ごはん代をサポート)したいという人がいれば、 LINEスタンプ や【くるるの野望ショップ】でフクロウグッズを購入して頂けると嬉しいです。
また、ブログ『はやぶさの技術ノート』では、本記事も含め多くのチュートリアル記事を無料で公開しています。SNSなどで友達にも教えてあげてほしいです!
【本ブログのサポート方法】
- LINEスタンプ を購入
- 【くるるの野望ショップ】でフクロウグッズを購入
- 本ブログの記事をSNS(Twitterやfacebookなど)でシェア