簡単レシート印刷 receiptline と 20 行の JavaScript でレジプリンターをインスタントカメラにしてみた

日本発のオープンソース receiptline でレシート印刷に少しずつトライしています。
今回は、[前回](https://qiita.com/dopperi46/items/7584bb72f56ad1dc8e31)のレシートプリンターと変換 API を使ってアプリを作ります。

# 実はこれを作りたかった

“レジプリンター式インスタントカメラで「レシート日記」はなぜ楽しいのか？”
https://weekly.ascii.jp/elem/000/004/004/4004167/

“1枚1円の安さが正義、レシート現像のトイカメラが楽しい｜ベストバイ2019”
https://japanese.engadget.com/jp-2019-12-23-1-1-2019.html

“むしろ大人が欲しい多機能ぶり！ プリンター内蔵の子ども用カメラ「myFirst Camera Insta 2」”
https://capa.getnavi.jp/news/339006/

そうです。インスタントカメラです。
記事を読んでいるだけで楽しさが伝わってきます。

早速これを receiptline で作ります。
もちろんカメラデバイスが必要です。

# インスタントカメラのコード

アプリの開発環境は何でも構わないのですが、最短コースで。
receiptline の Node.js サンプルプログラムをベースにします。

作業フォルダを作成して `example/nodejs` 以下をまるごとコピー。
コピーした `wwwroot/index.html` 書き換えます。

```html:wwwroot/index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Instant Camera</title>
    <script type="text/javascript">
        async function initialize() {
            const video = document.querySelector('video');
            const canvas = document.querySelector('canvas');
            // video
            video.srcObject = await navigator.mediaDevices.getUserMedia({ audio: false, video: true });
            video.onclick = event => {
                // image
                canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
                let data = `{i:${canvas.toDataURL('image/png').slice(22)}}\n`;
                // barcode
                const now = new Date();
                const iso = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();
                data += `{c:${iso.replace(/\D/g, '').slice(2, 14)};o:ean,24}|`;
                // send data
                const xhr = new XMLHttpRequest();
                xhr.open('POST', 'printer');
                xhr.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');
                xhr.send(data);
            };
        }
    </script>
</head>
<body onload="initialize()">
    <video autoplay style="width: 100%;"></video>
    <canvas width="576" height="432" style="display: none;"></canvas>
</body>
</html>
```

20 行の JavaScript コードで出来てしまいました。

## 写真サイズ

576 × 432 ピクセルに固定してあります。
レシートプリンターの幅に合わせて Canvas のサイズを変更してください。

- TM-T88V (80mm)
  - 512 × 384 ピクセル
- mC-Print3 (80mm)
  - 576 × 432 ピクセル (変更不要)

```html
<canvas width="576" height="432" style="display: none;"></canvas>
```

## 撮影日時

バーコードで撮影日時を印刷しています。
2023 年 7 月 20 日 12 時 34 分 56 秒の場合。

- データ (12 桁)
  - `23` (年)
  - `07` (月)
  - `20` (日)
  - `12` (時)
  - `34` (分)
  - `56` (秒)
- チェックデジット (1 桁)
  - `1` (自動計算)

バーコードの種類は JAN (EAN) コードです。
バーコード / QR コードリーダーアプリで読み取ることができます。

```text:ReceiptLine
{c:230720123456;o:ean,24}|
```

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669512/f2ba7891-11c7-daa6-b40c-5f8f451de17b.png)

## プリント先

プリンター ID を `printer` に固定してあります。
印刷設定に合わせて変更することができます。

```javascript
xhr.open('POST', 'printer');
```

# 印刷設定

コピーした `printers.json` で設定します。
使用するレシートプリンターに合わせて調整が必要です。
特にガンマ補正 `gamma` の値は写真の画質に影響します。

## TM-T88V (80mm)

```json:printers.json
{
    "printer": {
        "host": "192.168.1.2",
        "port": 9100,
        "cpl": 42,
        "encoding": "cp932",
        "gamma": 1.8,
        "upsideDown": false,
        "command": "escpos"
    }
}
```

## mC-Print3 (80mm)

```json:printers.json
{
    "printer": {
        "host": "192.168.1.3",
        "port": 9100,
        "cpl": 48,
        "encoding": "cp932",
        "gamma": 1.8,
        "upsideDown": true,
        "command": "starmbcs"
    }
}
```

# いざ撮影！

サーバーを起動します。実行環境は Windows 10 です。

```bash
$ node start.js
```

起動後、`http://localhost:10080` を開きます。
カメラに対するアクセス権を求められるので許可してください。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669512/0270d813-2a04-9112-c51f-42ea676a959d.png)

映像だけのシンプルなページです。クリックすると即時印刷します。

![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669512/027e0834-3a7b-ef3b-3ee4-f44d32bf3213.jpeg)

![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669512/0ae7d909-b7b5-58ba-6db1-e0d61f903e9b.jpeg)

業務用レジプリンタ式インスタントカメラ、略して “レジカメ” 誕生です！

# 新たな可能性

インスタ時代の新型プリントシール機が発売されたそうです。

“セガ、最新プリクラ機「fiz」でプリントシール機市場に20年ぶりの再参入”
https://weekly.ascii.jp/elem/000/004/019/4019040/

ふと思いました。これも出来るのでは！？
Canvas でキャプチャした画像を加工すればいいのです。
スタンプ押してよし、文字を入れてよし、ご当地フレームもよし。

しかも、業務用レジプリンタ式なら、このような特長もあります。

- 圧倒的低コスト！
- お財布といつも一緒！
- 盛らなくても映える！ (個人の感想です)

撮り放題にして集客するなど、プリントシール機と違うビジネスが生まれそうな予感。

これにて receiptline シリーズは一旦完結。
また何か作ったら投稿します。ではまた！

![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669512/e3bc6088-b7b1-758b-e622-bc702c941c92.jpeg)