LoginSignup
8
4

More than 3 years have passed since last update.

バナー作成をProcessingで完結したい

Last updated at Posted at 2020-12-12

Processing Advent Calender 2020 12日目です!

私が所属するクリエイティブコーディングサークル「ARTiS」は,不定期で開催した8回のワークショップごとに,テーマに合わせたバナーをProcessingだけで作っています.

開催するイベントのバナーを作るとき,どんなツールを使いますか?
グラフィック編集ツールで作る方が多いのではないでしょうか.

クリエイティブコーディングに関わるイベントであれば,Processing/p5.jsなどで描いたグラフィックをもとに,バナーを作ると思います.
作品を一度Processing/p5.jsで作ったものを他のソフトにインポートし,情報を付加し,エクスポートする...少し手数が増えますね.
それなら,コードを実行するだけで,バナーを完成できるようにしてしまいましょう.

本記事では,Workshop#2 "Noise"のバナーを例に,Processingで実現します(p5.js版に翻訳できなかった).

実装

以下2つを作成します.

  1. バナー背景に使いたい作品
  2. イベント名,開催日時,ロゴなどを描画するレイヤー(TypeLayer)

最終的には,1.の作品が文字の邪魔をしないように,filterでぼかしを入れます.
TypeLayerは,ProcessingのPGraphicsを利用して実装します.
1.の前面に2.のTypeLayerを描画して,最後に画像として出力し完成です.

バナー背景に使いたい作品を描画

スライドの表紙にも使うことを考えて,縦横比を縦:横=9:16にします.
例ではsize(1280, 720)とします.

まずは,背景にするグラフィックを作成してみます.
7色の折れ線グラフみたいなものを,ノイズを使って適当に作ります.
↓こんなやつです

BannerExample1.png

Banner.pde
float offset = 0.0;
float distance = 0.01;

void setup() {
  size(1280, 720);
  background(0);
  colorMode(HSB, 360, 100, 100, 100);
}

void draw() {
  noiseSeed(0);
  drawNoise(color(0, 100, 100));
  noiseSeed(1);
  drawNoise(color(30, 100, 100));
  noiseSeed(2);
  drawNoise(color(60, 100, 100));
  noiseSeed(3);
  drawNoise(color(90, 100, 100));
  noiseSeed(4);
  drawNoise(color(120, 100, 100));
  noiseSeed(5);
  drawNoise(color(210, 100, 100));
  noiseSeed(6);
  drawNoise(color(270, 100, 100));
  offset += distance;

  // 終了条件
  if (width <= (offset+distance)*100) {
    noLoop();
  }
}

void drawNoise(color c) {
  stroke(c, 50);
  strokeWeight(5);
  float x = offset*100;
  float x_next = (offset+distance)*100;
  float y = map(noise(offset), 0, 1, 0, height);
  float y_next = map(noise(offset+distance), 0, 1, 0, height);
  line(x, y, x_next, y_next);
}

イベント名,開催日時,ロゴなどを描画するレイヤー

作品の上に文字情報などを表示するため,TypeLayerクラスを作ってみます.
文字に使うフォントは"Avenir-Black"を選択しました.
サークルのバナーなので,サークルのロゴ(svg形式)をloadShapeで読み込んでいます.
(再現するときは,適宜置換・削除してください)

TypeLayer.pde
class TypeLayer {

  PGraphics pg;
  PShape logo;

  TypeLayer() {
    this.pg = createGraphics(width, height);
    this.logo = pg.loadShape("ArtisLogo_v1.1.svg");
    generate();
  }

  void generate() {
    pg.beginDraw();
    pg.background(0, 30);
    pg.colorMode(HSB, 360, 100, 100, 100);
    pg.textAlign(LEFT, CENTER);
    pg.textFont(createFont("Avenir-Black", 80));
    pg.fill(0, 0, 100);
    pg.text("BannerExample", 100, height/2-45);
    pg.textSize(40);
    pg.text("2020.12.12(Sun)" + " " + "12:30-14:00", 100, height/2+45);
    pg.shape(logo, width-logo.width/3-54, height-logo.height/3-20, logo.width/3, logo.height/3);
    pg.endDraw();
  }

  void draw() {
    image(pg, 0, 0);
  }

}

TypeLayerクラスのインスタンスを生成することで,文字やロゴが描画されたレイヤーが完成します.
TypeLayerクラスインスタンスの生成はsetup()内で行い,折れ線グラフみらいなグラフィックができた直後に,インスタンスのdraw()を呼び出し描画します.

Banner.pde
float offset = 0.0;
float distance = 0.01;

// ここから追加
TypeLayer typeLayer;
// ここまで追加

void setup() {
  size(1280, 720);
  background(0);
  colorMode(HSB, 360, 100, 100, 100);

  // ここから追加
  typeLayer = new TypeLayer();
  // ここまで追加
}
Banner.pde
void draw() {
  noiseSeed(0);
  drawNoise(color(0, 100, 100));
  noiseSeed(1);
  drawNoise(color(30, 100, 100));
  noiseSeed(2);
  drawNoise(color(60, 100, 100));
  noiseSeed(3);
  drawNoise(color(90, 100, 100));
  noiseSeed(4);
  drawNoise(color(120, 100, 100));
  noiseSeed(5);
  drawNoise(color(210, 100, 100));
  noiseSeed(6);
  drawNoise(color(270, 100, 100));
  offset += distance;

  if (width <= (offset+distance)*100) {

    // ここから追加
    typeLayer.draw();
    // ここまで追加

    noLoop();
  }
}

実行してみると,下図のように文字とロゴが表示されます.

BannerExample1.png

見やすさのための調整

いまの状態だと背景の主張がうるさいので,少しだけぼかしを入れてみます.
そして,この状態をsaveFrameで書き出してみます.

Banner.pde
void draw() {
  noiseSeed(0);
  drawNoise(color(0, 100, 100));
  noiseSeed(1);
  drawNoise(color(30, 100, 100));
  noiseSeed(2);
  drawNoise(color(60, 100, 100));
  noiseSeed(3);
  drawNoise(color(90, 100, 100));
  noiseSeed(4);
  drawNoise(color(120, 100, 100));
  noiseSeed(5);
  drawNoise(color(210, 100, 100));
  noiseSeed(6);
  drawNoise(color(270, 100, 100));
  offset += distance;

  // 終了条件
  if (width <= (offset+distance)*100) {

    // ここから追加
    filter(BLUR, 2);
    // ここまで追加

    typeLayer.draw();

    // ここから削除
    noLoop();
    // ここまで削除

    // ここから追加
    saveFrame("Banner.png");
    exit();
    // ここまで追加
  }
}

BannerExample1.png

背景にぼかしをいれるとこうなります.見やすくなりましたね.
これで,コードだけでバナー作成を完結できました.

掲載したコードのまとめ

Banner.pde
TypeLayer typeLayer;

float offset = 0.0;
float distance = 0.01;

void setup() {
  size(1280, 720);
  background(0);
  colorMode(HSB, 360, 100, 100, 100);

  typeLayer = new TypeLayer();
}

void draw() {
  noiseSeed(0);
  drawNoise(color(0, 100, 100));
  noiseSeed(1);
  drawNoise(color(30, 100, 100));
  noiseSeed(2);
  drawNoise(color(60, 100, 100));
  noiseSeed(3);
  drawNoise(color(90, 100, 100));
  noiseSeed(4);
  drawNoise(color(120, 100, 100));
  noiseSeed(5);
  drawNoise(color(210, 100, 100));
  noiseSeed(6);
  drawNoise(color(270, 100, 100));
  offset += distance;

  // 終了条件
  if (width <= (offset+distance)*100) {
    filter(BLUR, 2);
    typeLayer.draw();
    saveFrame("Banner.png");
    exit();
  }
}

void drawNoise(color c) {
  stroke(c, 50);
  strokeWeight(5);
  float x = offset*100;
  float x_next = (offset+distance)*100;
  float y = map(noise(offset), 0, 1, 0, height);
  float y_next = map(noise(offset+distance), 0, 1, 0, height);
  line(x, y, x_next, y_next);
}
TypeLayer.pde
class TypeLayer {

  PGraphics pg;
  PShape logo;

  TypeLayer() {
    this.pg = createGraphics(width, height);
    this.logo = pg.loadShape("ArtisLogo_v1.1.svg");
    generate();
  }

  void generate() {
    pg.beginDraw();
    pg.background(0, 30);
    pg.colorMode(HSB, 360, 100, 100, 100);
    pg.textAlign(LEFT, CENTER);
    pg.textFont(createFont("Avenir-Black", 80));
    pg.fill(0, 0, 100);
    pg.text("BannerExample", 100, height/2-45);
    pg.textSize(40);
    pg.text("2020.12.12(Sun)" + " " + "12:30-14:00", 100, height/2+45);
    pg.shape(logo, width-logo.width/3-54, height-logo.height/3-20, logo.width/3, logo.height/3);
    pg.endDraw();
  }

  void draw() {
    image(pg, 0, 0);
  }

}
8
4
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
8
4