戻る:アニメ編(その五) |
基本テクニック:拡大縮小
今回は画像の拡大縮小を一時描画で行う方法を説明します。
描画、一時描画とも拡大縮小のためのパラメータというのはありませんが、画像サイズを表すふたつのパラメータ、つまり width と height を適切に変更すれば、それに追従して画像は拡大ないし縮小されます。
次の JPY ファイルは、地図画像を背景に画面中央あたりから冒険者の宿画像を拡大させます。
1: [init] 2: 3: [地図] 4: fileName=MapOfWirth.bmp 5: dirtype=2 6: transparent=0 7: animation=1 8: 9: [冒険者の宿] 10: fileName=AdventurersInn.bmp 11: dirtype=2 12: savecache=1 13: position=116,15 14: transparent=0 15: 16: [冒険者の宿_000] 17: width=80 18: height=52 19: loadcache=1 20: visible=0 21: transparent=0 22: animation=3 23: animeposition=276,119 24: wait=200 25: 26: [冒険者の宿_001] 27: width=160 28: height=104 29: loadcache=1 30: visible=0 31: transparent=0 32: animation=3 33: animeposition=236,93 34: wait=200 35: 36: [冒険者の宿_002] 37: width=240 38: height=156 39: loadcache=1 40: visible=0 41: transparent=0 42: animation=3 43: animeposition=196,67 44: wait=200 45: 46: [冒険者の宿_003] 47: width=320 48: height=208 49: loadcache=1 50: visible=0 51: transparent=0 52: animation=3 53: animeposition=156,41 54: wait=200 55: 56: [冒険者の宿_004] 57: width=400 58: height=260 59: loadcache=1 60: visible=0 61: transparent=0 62: animation=3 63: animeposition=116,15 64: wait=200
それでは動作を見てみましょう。
解説
前述の JPY ファイルで画像拡大の一時描画を行っているのは [冒険者の宿_000] ~ [冒険者の宿_004] までの箇所で、キーになるのは前述の通り width と height のパラメータです。このパラメータの設定値だけを抜き出してみましょう。
セクション | width | height | (割合) |
---|---|---|---|
[冒険者の宿_000] | 80 | 52 | 20% |
[冒険者の宿_001] | 160 | 104 | 40% |
[冒険者の宿_002] | 240 | 156 | 60% |
[冒険者の宿_003] | 320 | 208 | 80% |
[冒険者の宿_004] | 400 | 260 | 100% |
画像の縦と横の比率をアスペクト比といいますが、拡大縮小の際にはこのアスペクト比を一定に保ったまま、サイズを連続的に変更させます。このケースでは元の画像のサイズ(400*260)に対して、20% → 40% → 60% → 80% → 100% と変化していることがわかるでしょう。
変化の割合を細かくすると、それにあわせて画像の変化も細かくなります。
次の例では画像のサイズを 5% ずつ、つまり幅は 20 ピクセルずつ、高さは 13 ピクセルずつ変化させています(ウェイトは 50 ミリ秒)。
これらの例はいわば等差数列的に画像のサイズを変更させていますが、動作がダイナミックさに欠ける嫌いがあります。
これを等比数列的に画像のサイズを変更させると、印象が少し変わります。
だいぶ動きにメリハリがつきましたね。これは画像サイズを一定値ずつ増やすのではなく、あるセクションは常に前のセクションの x 倍*1になるようにする、というルールの元に変化させたものです。
JPY ファイルのサイズが大きいのでソースコードは割愛し、サイズの比較だけを示します。
セクション | 等差 w | 等差 h | 等比 w | 等比 h |
---|---|---|---|---|
冒険者の宿_000 | 20 | 13 | 5 | 3 |
冒険者の宿_001 | 40 | 26 | 7 | 4 |
冒険者の宿_002 | 60 | 39 | 9 | 5 |
冒険者の宿_003 | 80 | 52 | 11 | 7 |
冒険者の宿_004 | 100 | 65 | 14 | 9 |
冒険者の宿_005 | 120 | 78 | 17 | 11 |
冒険者の宿_006 | 140 | 91 | 21 | 13 |
冒険者の宿_007 | 160 | 104 | 27 | 17 |
冒険者の宿_008 | 180 | 117 | 34 | 22 |
冒険者の宿_009 | 200 | 130 | 42 | 27 |
冒険者の宿_010 | 220 | 143 | 53 | 34 |
冒険者の宿_011 | 240 | 156 | 67 | 43 |
冒険者の宿_012 | 260 | 169 | 83 | 53 |
冒険者の宿_013 | 280 | 182 | 104 | 67 |
冒険者の宿_014 | 300 | 195 | 131 | 85 |
冒険者の宿_015 | 320 | 208 | 163 | 105 |
冒険者の宿_016 | 340 | 221 | 204 | 132 |
冒険者の宿_017 | 360 | 234 | 256 | 166 |
冒険者の宿_018 | 380 | 247 | 320 | 208 |
冒険者の宿_019 | 400 | 260 | 400 | 260 |
マスク画像の拡大縮小
画像を覆うマスクを拡大縮小させることで、アイリスアウト/アイリスインという場面転換の手法を実現することが出来ます。
これは 1960 ~ 70 年代の映像作品で盛んに用いられた手法で、今日でもレトロさを表現するために(主にコメディで)使われているものです。
論より証拠、まずは実際に見てみてください。
これは表示されている背景画像を拡大縮小するのではなく、それを部分的に覆い隠すマスク画像を用意しておき、そのサイズを特定の点に向かって縮小(あるいは特定の点から拡大)することでこのような効果を得ることが出来ます。
ここで用いたマスク画像はこのようなものです。
一見して何の変哲もない円の画像ですが、左上の1ピクセルと中央の円が同色になっていて、透過色として使えるようになっているところがミソです。これを画像に重ねると中央の円形部分だけが抜けて表示される仕組みになっており、このマスク画像のサイズを連続的に変化させることで上述のような効果を得ることが出来るわけです。
更にこの JPY では演出効果を狙い、娘さんの顔に向かって縮小したタイミング、及び一時描画の最後にポーズを入れています。
JPYソースを表示
1: [init] 2: 3: [frame000] 4: width=128 5: height=128 6: fileName=06_MaskCircle.bmp 7: savecache=1 8: visible=0 9: 10: [frame001] 11: width=891 12: height=891 13: loadcache=1 14: visible=0 15: animation=1 16: animeposition=-6,-326 17: wait=50 18: 19: [frame002] 20: width=776 21: height=776 22: loadcache=1 23: visible=0 24: animation=1 25: animeposition=52,-268 26: wait=50 27: 28: [frame003] 29: width=675 30: height=675 31: loadcache=1 32: visible=0 33: animation=1 34: animeposition=102,-218 35: wait=50 36: 37: [frame004] 38: width=588 39: height=588 40: loadcache=1 41: visible=0 42: animation=1 43: animeposition=146,-174 44: wait=35 45: 46: [frame005] 47: width=512 48: height=512 49: loadcache=1 50: visible=0 51: animation=1 52: animeposition=184,-136 53: wait=35 54: 55: [frame006] 56: width=445 57: height=445 58: loadcache=1 59: visible=0 60: animation=1 61: animeposition=217,-103 62: wait=35 63: 64: [frame007] 65: width=388 66: height=388 67: loadcache=1 68: visible=0 69: animation=1 70: animeposition=246,-74 71: wait=35 72: 73: [frame008] 74: width=337 75: height=337 76: loadcache=1 77: visible=0 78: animation=1 79: animeposition=271,-49 80: wait=35 81: 82: [frame009] 83: width=294 84: height=294 85: loadcache=1 86: visible=0 87: animation=1 88: animeposition=293,-27 89: wait=35 90: 91: [frame010] 92: width=256 93: height=256 94: loadcache=1 95: visible=0 96: animation=1 97: animeposition=312,-8 98: wait=35 99: 100: [frame011] 101: width=222 102: height=222 103: loadcache=1 104: visible=0 105: animation=1 106: animeposition=329,9 107: wait=35 108: 109: [frame012] 110: width=194 111: height=194 112: loadcache=1 113: visible=0 114: animation=1 115: animeposition=343,23 116: wait=35 117: 118: [frame013] 119: width=168 120: height=168 121: loadcache=1 122: visible=0 123: animation=1 124: animeposition=356,36 125: wait=35 126: 127: [frame014] 128: width=147 129: height=147 130: loadcache=1 131: visible=0 132: animation=1 133: animeposition=366,46 134: wait=35 135: 136: [frame015] 137: width=128 138: height=128 139: loadcache=1 140: visible=0 141: animation=1 142: animeposition=376,56 143: wait=35 144: 145: [pause] 146: animation=4 147: wait=1000 148: 149: [frame016] 150: width=111 151: height=111 152: loadcache=1 153: visible=0 154: animation=1 155: animeposition=384,64 156: wait=35 157: 158: [frame017] 159: width=97 160: height=97 161: loadcache=1 162: visible=0 163: animation=1 164: animeposition=391,71 165: wait=35 166: 167: [frame018] 168: width=84 169: height=84 170: loadcache=1 171: visible=0 172: animation=1 173: animeposition=398,78 174: wait=35 175: 176: [frame019] 177: width=73 178: height=73 179: loadcache=1 180: visible=0 181: animation=1 182: animeposition=403,83 183: wait=35 184: 185: [frame020] 186: width=64 187: height=64 188: loadcache=1 189: visible=0 190: animation=1 191: animeposition=408,88 192: wait=35 193: 194: [frame021] 195: width=55 196: height=55 197: loadcache=1 198: visible=0 199: animation=1 200: animeposition=412,92 201: wait=35 202: 203: [frame022] 204: width=48 205: height=48 206: loadcache=1 207: visible=0 208: animation=1 209: animeposition=416,96 210: wait=35 211: 212: [frame023] 213: width=42 214: height=42 215: loadcache=1 216: visible=0 217: animation=1 218: animeposition=419,99 219: wait=35 220: 221: [frame024] 222: width=36 223: height=36 224: loadcache=1 225: visible=0 226: animation=1 227: animeposition=422,102 228: wait=35 229: 230: [frame025] 231: width=32 232: height=32 233: loadcache=1 234: visible=0 235: animation=1 236: animeposition=424,104 237: wait=35 238: 239: [frame026] 240: width=27 241: height=27 242: loadcache=1 243: visible=0 244: animation=1 245: animeposition=426,106 246: wait=35 247: 248: [frame027] 249: width=24 250: height=24 251: loadcache=1 252: visible=0 253: animation=1 254: animeposition=428,108 255: wait=35 256: 257: [frame028] 258: width=21 259: height=21 260: loadcache=1 261: visible=0 262: animation=1 263: animeposition=429,109 264: wait=35 265: 266: [frame029] 267: width=18 268: height=18 269: loadcache=1 270: visible=0 271: animation=1 272: animeposition=431,111 273: wait=35 274: 275: [frame030] 276: width=632 277: height=420 278: color=$000000 279: transparent=0 280: animation=1 281: 282: [pause]
まとめとおさらい
画像の拡大縮小というのはそれほど使う機会があるわけではありませんが、使い方によっては面白い効果を得ることが出来ます。
今回のポイントは下記の通りです。
- 一定のアスペクト比を保ったまま画像のサイズを変更させる
- 等差数列的にサイズを変更するより等比数列的に変更した方がメリハリが出る
- マスク画像を拡大縮小することも可能
次回は場面転換の基本的手法であるフェイドを取り上げます。
戻る:アニメ編(その五) |
*1 この例では 1.25 倍
コメント
最新を表示する
NG表示方式
NGID一覧