JRubyでglitch iconを作る(2)
プラグイン機構を採用し、ランダムにいろいろ作れるようにしてみた。
普通はjpegとかのバイナリを直接いじるみたいだけどよく分からないのでJRubyでjavax.imageioを使ってやっている。
ランダムに96個作ってみて8×12に敷き詰めてみたのがこれ。
で、定期的にランダムに作ってtwitterのアイコンとしてアップロードしてる。
敷き詰めるのはImageMagickと一緒にインストールされるmontageコマンドでできる montageコマンド – 橋本詳解
ソースコードは全てgithubに置いた。
■仕組み
単機能モジュールをランダムに連結する事である程度ランダムな画像を生成できる。
javax.imageio.BufferedImageのインスタンスを受け取り、少し加工して返すというJRubyのmoduleをプラグインとし、それらをGlitchというclassがランダムに呼び出す。
今のところプラグインは23種類ある。単体だとそれほど派手にはならない。
■プラグイン
http://github.com/shokai/glitchicon/tree/master/plugins/にある。
pluginが動くルールはこれ。
- pluginsディレクトリの中に置いておく
- ファイル名末尾が.rbである
- JRubyのmoduleである
- ファイル名の先頭1文字を大文字にしたmodule名である
- BufferedImageを受け取って、同じサイズのBufferedImageを返す glitch(BufferedImage) というstatic methodを持つ
- 受け取ったBufferedImageに対しては破壊的に処理しても、そうでなくてもいい
プラグインはBufferedImageの処理に集中できるように、他の事はglitch.rbがやる。
どのプラグインも簡単にできている。30行ぐらい。
drumroll_verticalプラグインの場合(画像では一番左、下から2番目)
#!/usr/bin/env jrubyランダムに縦に区切って、ランダムにスロットのドラムみたいにずらす。
require 'java'
import 'java.lang.System'
import 'javax.imageio.ImageIO'
import 'java.awt.image.BufferedImage'
module Drumroll_vertical
def Drumroll_vertical.glitch(img)
img_result = BufferedImage.new(img.width, img.height, img.type)
roll = 0
for x in 0...img.width do
roll = rand(img.height) if rand > 0.95
roll = 0 if rand > 0.95
for y in 0...img.height do
pix = img.get_rgb(x, y)
y2 = y+roll
y2 -= img.height if y2 > img.height-1
img_result.set_rgb(x, y2, pix)
end
end
return img_result
end
end
色を反転させるcolor_reverseプラグイン
#!/usr/bin/env jruby
require 'java'
import 'java.lang.System'
import 'javax.imageio.ImageIO'
import 'java.awt.image.BufferedImage'
module Color_reverse
def Color_reverse.glitch(img)
for y in 0...img.height do
for x in 0...img.width do
pix = img.get_rgb(x, y)
r = pix >> 16 & 0xFF
g = pix >> 8 & 0xFF
b = pix & 0xFF
r = 256-r
g = 256-g
b = 256-b
pix = ((r << 16)&0xFF0000 | (g << 8)&0xFF00 | b)
img.set_rgb(x,y, pix)
end
end
return img
end
end
量子化した後に輪郭抽出するquantize_contour
#!/usr/bin/env jruby
require 'java'
import 'java.lang.System'
import 'javax.imageio.ImageIO'
import 'java.awt.image.BufferedImage'
module Quantize_contour
def Quantize_contour.glitch(img)
for y in 0...img.height do
for x in 0...img.width do
pix = img.get_rgb(x, y)
r = pix >> 16 & 0xFF
g = pix >> 8 & 0xFF
b = pix & 0xFF
gray = (r+g+b)/3
quant = gray & 0xC0
pix = ((quant << 16)&0xFF0000 | (quant << 8)&0xFF00 | quant)
img.set_rgb(x, y, pix)
end
end
img_result = BufferedImage.new(img.width, img.height, img.type)
for y in 1...img.height-1 do
for x in 1...img.width-1 do
pix = img.get_rgb(x, y)
around = (img.get_rgb(x-1,y)+img.get_rgb(x+1,y)+img.get_rgb(x,y-1)+img.get_rgb(x,y+1))/4
if around < pix
pix = 0
else
pix = 0xFFFFFF
end
img_result.set_rgb(x, y, pix)
end
end
return img_result
end
end
そんなかんじ。画像をいじるけど、元の画像を知っている人なら元画像を思い浮かべられる程度にglitchしたい。