ProcessingでQRコードを使う

こちらに移行しました。

https://blog.enkatsu.org/posts/processing-qrcode/

<!--

# はじめに

この記事は[Processing Advent Calendar 2017](https://qiita.com/advent-calendar/2017/processing) 24日目の記事です。
そういえば24日ってクリスマスイブですね。
何も考えずに参加したので、クリスマス感は薄い記事になると思います。

# ProcessingでQRコードを使う

ProcessingでQRコードを使う為のライブラリは有名なところだと、
Daniel Shiffmanの[qrcode-processing](http://shiffman.net/p5/qrcode-processing/)があります。
ですが今回は[ZXingP5](https://github.com/enkatsu/ZXingP5)という、Java製のQRコードライブラリ[ZXing](https://github.com/zxing/zxing)のProcessingラッパーを使います。

このライブラリの特徴はQRコードの左上、右上、左下にある四角形の座標が取得できることです。
なのでこのようにQRコードの位置と大きさ、角度や文字情報などを取得することができます。
実はこのライブラリは自分が作ったので、コメントやIssueをいただけたら、
修正や改良をしたいと思います。

![sample](https://raw.githubusercontent.com/enkatsu/ZXingP5/master/img/top.png)

ではでは使い方を書いていきます。

# インストール

[ここ](https://github.com/enkatsu/ZXingP5/archive/master.zip)からZipをダウンロードして、解凍したディレクトリを`ZXingP5`にリネームして、`PROCESSING_PATH/library`に配置、
もしくはターミナルで以下のコマンドを実行します。

```bash
cd PROCESSING_PATH/library
git clone https://github.com/enkatsu/ZXingP5.git
```

# 使い方

サンプルは3つ入っていて内容はこのようになっています。

- WriterSample...文字列からQRコードのPImageを生成するサンプル
- ReaderSample...QRコードの映ったPImageから文字列を読み取るサンプル
- ReaderAdvancedSample...QRコードの映ったPImageから文字列と座標、大きさを読み取るサンプル

一つずつ説明しようと思ったんですが、
見直してみたら説明するほどコード量が多くないので、
ReaderAdvancedSampleをいじってクリスマスっぽくしようと思います。

元のReaderAdvancedSampleはこんな感じです。

```java
import processing.video.*;
import com.github.endoh0509.zxingp5.*;

Capture cam;
QRReader reader;

void setup() {
  size(320, 240);

  cam = new Capture(this, 320, 240);
  cam.start();
  reader = new QRReader(this);
}

void draw() {
  if (cam.available()) {
    cam.read();
    image(cam, 0, 0);
    tint(255, 200);
    String txt = reader.decode(cam);
    if (txt != null) {
      PVector[] points = reader.getPoints();
      PVector lowerLeft = points[0];
      PVector upperLeft = points[1];
      PVector upperRight = points[2];

      // Get QR Code position
      PVector vec = PVector.sub(lowerLeft, upperRight);
      PVector center = PVector.mult(vec, 0.5).add(upperRight);
      
      // Get QR Code angle
      PVector qrVertical = PVector.sub(upperLeft, lowerLeft);
      PVector camVertical = new PVector(0, 1);
      float angle = atan2(qrVertical.y - camVertical.y, qrVertical.x - camVertical.x);
      if (angle < 0) { 
        angle += TWO_PI;
      }
      
      // Get QR Code scale
      float scale = PVector.dist(upperLeft, upperRight);
      
      noStroke();
      fill(255, 200);
      rectMode(CENTER);
      pushMatrix();
      translate(center.x, center.y);
      rotate(angle);
      rect(0, 0, scale, scale);
      popMatrix();
      
      textAlign(CENTER, CENTER);
      textSize(scale);
      fill(#193EA2);
      text(txt, center.x, center.y);
    }
  }
}
```

QRコードが読み取れた時だけ、
最初に載せた写真のように、
QRコードの位置と大きさ、角度を使って四角形を描画して、
その上に文字情報を表示しています。

これに画像をURLからロードしてくる感じにするとこんな風になります。

```java
import processing.video.*;
import com.github.endoh0509.zxingp5.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Capture cam;
QRReader reader;
PImage img;

void setup() {
  size(320, 240);
  imageMode(CENTER);
  cam = new Capture(this, 320, 240);
  cam.start();
  reader = new QRReader(this);
  img = null;
}

void draw() {
  if (cam.available()) {
    cam.read();
    image(cam, width / 2, height / 2);
    String url = reader.decode(cam);
    if (url != null) {
      if (img == null && isImageURL(url)) {
        img = loadImage(url);
      } else if (img != null) {
        PVector[] points = reader.getPoints();
        PVector lowerLeft = points[0];
        PVector upperLeft = points[1];
        PVector upperRight = points[2];

        // Get QR Code position
        PVector vec = PVector.sub(lowerLeft, upperRight);
        PVector center = PVector.mult(vec, 0.5).add(upperRight);

        // Get QR Code angle
        PVector qrVertical = PVector.sub(upperRight, upperLeft);
        PVector camVertical = new PVector(0, 1);
        float angle = atan2(qrVertical.y - camVertical.y, qrVertical.x - camVertical.x);
        if (angle < 0) { 
          angle += TWO_PI;
        }

        // Get QR Code scale
        float scale = PVector.dist(upperLeft, upperRight);

        pushMatrix();
        translate(center.x, center.y);
        rotate(angle);
        image(img, 0, 0, scale, scale);
        popMatrix();
      }
    }
  }
}

boolean isImageURL(String urlStr) {
  String pattern = "(http(s?):/)(/[^/]+)+" + "\\.(?:jpg|gif|png)";
  Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
  Matcher m = p.matcher(urlStr);
  return m.find();
}
```

<img width="320" alt="スクリーンショット 2017-12-21 22.33.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/80816/94f815bd-8827-fd27-9cf8-b93df54a6942.png">

使ったQRコードはこちらです。
(実際に使ったのとQRのバージョンが違うから少し違いますが)
だいぶクリスマスっぽくなりましたね。

![QR_Code1513877100.png](https://qiita-image-store.s3.amazonaws.com/0/80816/21c0b616-9a4e-7e23-eab5-4b24d68828f4.png)

ではではメリークリスマス。
そして良いお年を。

-->