22
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

vvvvAdvent Calendar 2016

Day 8

vvvvでJPGのglitchを実装した

Last updated at Posted at 2016-12-08

はじめに

vvvv Advent Calendar 2016 の8日目の記事です。

Glitchエフェクトいいですよね。とりあえずGlitchさせれば良い感じになる。
Twitter眺めてたら良い感じのvvvvによるグリッチ映像が流れてきて(↓のツイート)、心が癒やされました。

これに影響されて自分もグリッチ実装してみました。実装についてはこちらの記事が非常に参考になりました。

ただ、すべてを乱数に頼って実装したら思ったよりフォーマットごと壊れて真っ白になってしまう率が高かったので、JPGのファイルフォーマットを調べて壊していい箇所を探してみました。

JPGのファイルフォーマット

以下のサイトを参考にしました。
JPG ファイルフォーマット

AsRaw (EX9.Texture)でFileFormatを"JPG"に設定したところ、出力されるバイナリデータは以下の形になっていました。

開始バイト位置 セグメント種類 セグメント長
0 SOI(0xFFD8) 2 Byte
2 APP0(0xFFE0) 18 Byte
20 DQT(0xFFDB) 69 Byte
89 DQT(0xFFDB) 69 Byte
158 SOF0(0xFFC0) 19 Byte
177 DHT(0xFFC4) 33 Byte
210 DHT(0xFFC4) 183 Byte
393 DHT(0xFFC4) 33 Byte
426 DHT(0xFFC4) 183 Byte
609 SOS(0xFFDA) 14 Byte
623 イメージデータ 長い
最後の2Byte EOI(0xFFD9) 2 Byte

それぞれのセグメントについてグリッチしてうまくいくか試してみたところ、壊しても良さそうなセグメントがおおまかに特定できました。
また、セグメントによって得られるグリッチ効果がわかりやすく違ったので少し面白い結果になりました。

量子化テーブル定義セグメント(DQT)

DQTセグメントは2つありますが、両方とも壊して良さそうです。ただし、先頭から5Byteはセグメントのヘッダ部分なので触れないほうが良さそう。
というわけでDQTについては、バイト位置で言うと25~88Byte目、94~157Byte目がグリッチ対象です。

実際にグリッチをかけると下記のような映像が得られます。壊すバイト数をかなり増やしてもあまり原型崩れない感じ。
ちなみにグリッチ前の映像は以前の記事で作成したものです。

DQT.gif

ハフマン法テーブル定義セグメント(DHT)

DHTセグメントは4つあります。ただし、データ長が33Byteのセグメントはグリッチすると画像が表示されない場合が多かったので、避けたほうが良さそうです。
また、DHTセグメントにもヘッダ部分が19Byteあるので、グリッチの対象になるバイト位置は、231~392Byte目、447Byte目~608Byte目です。

ここにグリッチをかけると原色のノイズが入ってくるような映像が得られます。良いですね。
DHT.gif

イメージ実データ部

実際に圧縮された画像データなので基本的にいじって大丈夫はなず。最後の2ByteはEOIセグメントになっているので、そこだけ避ければあとはグリッチ可能な領域です。

ここをグリッチすると、画像がズレるようなそれらしいグリッチ結果が得られます。
IMAGE.gif

実装

patch.PNG

サブパッチ化して、各セグメントごとにグリッチする量を調節できるように実装しました。
JPGフォーマットのバイナリを符号なしByteのSpreadに変換した後、セグメントごとに書き換えるインデックスのバイナリを乱数で生成、さらに別の乱数で書き換え後の値を生成してグリッチしています。

乱数はRandom (Value)のIs IntegerピンをONにして整数で取り出しています。Scaleピンに入れる値は、生成したい乱数の数だけSelect (Value)で複製して入れてます。こうするとRandomSpread的に使うことができるのですが、もしかしたらコストは多少高いかもしれません。
書き換え後の値については、0xFFがJPGフォーマットのセグメント開始を意味してしまうので、0〜254までの範囲で生成するようにしてみました。

AsRawノードが1フレームごとにJPG変換しているので、当然ながらかなり重いです。

今回は単純に特定のインデックスを別の値に書き換える、という形でしか実装していませんが、画像データ部のある範囲を別の位置に移動とか、特定の数値を別の数値に置換とかやってみてもおもしろいかもしれないですね。

ソースはこちら。
vvvv-sandbox/20161208_WordpadGlitchJPG at master · clomie/vvvv-sandbox

22
9
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
22
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?