processingでモザイク処理をしたいと思います。
https://kumohara-tagebuch.hatenablog.com/entry/2022/05/16/013859
の続きみたいなもの。
使用している関数など(重要なもの)
get関数
PImage
のメソッドであるget()
を用いている。これは
Pimage img; int x=10 , y=10; img = loadImage("hoge.png"); int c = img.get(x,y);
のように使い、
get()
の返り値はint
型(整数)か、引数によってはPImage
を出す。今回は用いる画像の任意の1ピクセルの色が欲しいので、int型で扱う。
参考までに PImageのリファレンスはこちら processing.org get()のリファレンスはこちら processing.org
colorのリファレンスはこちら。 processing.org
colorとintの関係。
読み飛ばしても大丈夫。自分のメモ用に。
実はcolor型はint型と同義である。
バイナリで、
Aが透明度、Rが赤、Gが緑、Bが青色を示している。
AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB(2)
AARRGGBB(16)
であらわされる符号付32bitの整数である。
32bitでピンとくるかもしれないが、int型も符号付32bitである。
つまり、color col=color(255,255,0);
は、()内のものを、int型に直して(ちょっとこの表現は語弊が起きそうだけど)いる。
このことは、次のサンプルコードからもわかる。
int c1=0xffffff00;//16進数表記 int c2=0b11111111111111111111111100000000;//二進数表記 int c3=-256;//十進数表記(これは符号付二進数で保存されているため) color col=color(255, 255, 0); void setup() { size(350, 450); noLoop(); } void draw() { background(255); fill(col); rect(150, 50, 50, 50); fill(c1); rect(150, 150, 50, 50); fill(c2); rect(150,250,50,50); fill(c3); rect(150,350,50,50); }
fill()
はcolor型か、#ffffffか、0xffffffffで入れろとリファレンスでいわれているが、普通に十進数で入れても問題ないのである。(実用性は皆無だけど)
そして、bitシフトを用いることで、RGBの値のRだけ、Gだけ、Bだけを高速に出すことができる。
このリファレンスのサンプルコードにそのようなことができるコードがある。
モザイク処理のプログラムにも同じ挙動のものがあるが、わかりやすいように少しリファレンスのサンプルコードと異なる。
モザイク処理
自分が作ったコードは以下である。 img.get(i,j)で色を拾って、その色で同じ場所に円を書いてあるだけである。
float I=1;//読み込み画像の大きさを変える int n=2; char mode='a'; float m=5;//モザイクの粗さ PImage img;//画像を保存する変数 void setup() { img=loadImage("aiu.jpg");//画像読み込み。 surface.setResizable(true);//ここから二行の物はウィンドウサイズを可変にするため surface.setSize(int(img.width/I),int(img.height/I)); background(255); frameRate(5); //noLoop();//draw部のループはしない } void draw() { //image(img, 0, 0,width,height); colorMode(RGB, 255, 255, 255, 100);//colorModeをHSVに。しかしこのコードでは使っていない noStroke(); int r,g,b; color col=0; for (int i=0; i<width; i+=m) { for (int j=0; j<height; j+=m) { int c=img.get(i,j); r=(c & 0x00ff0000);//抜き出したいところ以外はすべて0にする。 g=(c & 0x0000ff00); b=(c & 0x000000ff); r=r>>2*8; g=g>>8; b=b>>0; if(mode=='r')col=color(r,0,0); if(mode=='g') col=color(0,g,0); if(mode=='b') col=color(0,0,b); if(mode== 'a' ) col=color(r,g,b); fill(col); ellipse(i,j,m,m); } } } void keyPressed() { if (key=='s'||key=='S')save("hue.png"); if (key=='r'||key=='R'){mode='r';background(255);} if (key=='g'||key=='G'){mode='g';background(255);} if (key=='b'||key=='B'){mode='b';background(255);} if (key=='a'||key=='A'){mode='a';background(255);} }
実行した結果は以下である。(ちなみに上記のままだと、noLoop()でないので、少し塗りつぶされていくのに注意。(じゃなきゃ、r,g,bそれぞれの値を抜き出した結果を出せないんだもん!!))