【Processing】createGraphics();とPGraphics

createGraphicsクラス

processingにPGraphicsというクラスがある。このクラスはprocessingのすべての描画面のインスタンスとして使われている。*1

processing.github.io

ディスプレイ外の描写をさせる時に使うとかリファレンスに書いてあるけど、よくわからん。活用方法はこの説明だとよくわからん。ほんとに。

自分の解釈をここに示す。

解釈と活用方法

PGraphicsはPImageの子クラスであると書いたが、当に、createGraphicsで画像を作成するというイメージでよいと思う。そしてその画像は描画可能のレイヤーと考えていいと思う。

processingのリファレンスのサンプルプログラムを以下に示す。

PGraphics pg;

void setup() {
  size(200, 200);
  pg = createGraphics(100, 100);
}

void draw() {
  pg.beginDraw();
  pg.background(102);
  pg.stroke(255);
  pg.line(pg.width*0.5, pg.height*0.5, mouseX, mouseY);
  pg.endDraw();
  image(pg, 50, 50); 
}

processing.org

これを実行してみると多少は理解ができよう。

pgという新しいレイヤーを作っていると考えてよいと思う。

図的理解

display window(processingでパソコンのウィンドウに描画されるもの)以外に描画できる仮想的なdisplayができるのだ。 少し書き換えてみる。

PGraphics pg;

void setup() {
  size(200, 200);
  pg = createGraphics(100, 100);
}

void draw() {
  background(0);
  ellipse(100,100,30,30);
  pg.beginDraw();
  pg.stroke(255);
  pg.clear();
  pg.line(pg.width*0.5, pg.height*0.5, mouseX, mouseY);
  pg.endDraw();
  image(pg, 50, 50); 
}

pg.clear()で、pgの画面をすべて透明なピクセルにするということである。

このようにレイヤー操作ができるようになる。 レイヤーの階層構造はimage()の描画順で指定できると考えていいだろう。

もうちょっと、PGraphicsのインスタンスを使って制御してみる。

PGraphics pg;

void setup() {
  size(700, 500);
  pg = createGraphics(100, 100);
  background(0);
}

void draw() {
  pgDraw();
  for (int i=0; i<height; i+=pg.height) {
    for (int j=0; j<width; j+=pg.width) {
      image(pg,j,i);
    }
  }
//  noLoop();
}

void pgDraw() {
  float x=random(20, 80);
  float y=random(20, 80);
  pg.beginDraw();
  pg.noStroke();
  pg.fill(0, 20);
  pg.rect(0, 0, pg.width, pg.height);
  pg.fill(255);
  pg.ellipse(x, y, 50, 50);
  pg.endDraw();
}

このようにタイルする時にも有効活用できる。

このタイリングのプログラムは

の本のp564を参考にした。

透過png画像を出力する。

上の結果のように(上の例ではわかりにくいが)PGraphicsは透明な背景に書かれるので、透過画像を出力できる。

上記のタイルした画像を透過png画像として出力したい。 タイルした結果をdisplayではなく、pg2に書いて、それをsaveする形にする。

PGraphics pg;
PGraphics pg2;
void setup() {
  size(700, 500);
  pg = createGraphics(100, 100);
  pg2 = createGraphics(700,500);
}

void draw() {
  pgDraw();
  for (int i=0; i<height; i+=pg.height) {
    for (int j=0; j<width; j+=pg.width) {
      pg2.beginDraw();
      pg2.image(pg,j,i);
      pg2.endDraw();
    }
  }
  image(pg2,0,0);
  pg2.save("create.png");
  noLoop();
}

void pgDraw() {
  float x=random(20, pg.width-20);
  float y=random(20, pg.height-20);
  pg.beginDraw();
  pg.noStroke();
  pg.fill(255,20);
  for(int i=0;i<20;i++){
   x=random(20, pg.width-20);
   y=random(20, pg.height-20);
  pg.ellipse(x, y, 50, 50);}
  pg.endDraw();
}

出力結果

透明度あり黄色にした結果

余談

createGraphics(width,height,P3D)のようにレンダラを指定もできる。

*1:ここで、開発者のページを見てみたら、PImageの子クラスらしい。へぇーと感嘆