関連記事
困っていること
まずは何あれ、問題定義!
私は、タスク管理ツールを何度も使ってみては、失敗してを繰り返しているのですが、それは、スマホでいちいちタスクを開くのが面倒くさいから、物理的に見えないからなのではないかと思い、プリンターで印刷してしまえばいいのではと思いこれらを作成しました。
機能
- プリンターで文字と画像を印刷する
- PILにフォントを設定する
使用するもの
- python3.6
- python-escposライブラリ
- Python Imaging Library
- OS(ubuntu18.04LTS)
- レシートプリンター
設計
1. 設定とコーディング1
まずはプリンターの設定と何がレシートプリンターでどんな文字が印刷できるかの調査
pythonで使用するライブラリをインストール
pip install python-escpos
pip install Pillow
フォントはフリーのフォントを使用させていただきました。
プリンターでの印刷
from escpos.printer import Usb
from escpos import *
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
# レシートプリンターを使った印刷
width = 500
height = 250
image = Image.new('1', (width, height), 255)
draw = ImageDraw.Draw(image)
font = ImageFont.truetype('FLOPDesignFont.ttf', 50, encoding='unic')
draw.text((0, 0), "日本語" + " ", font=font, fill=0)
font = ImageFont.truetype('FLOPDesignFont.ttf', 28, encoding='unic')
draw.text((0, 82), "abcdefghijklmnopqrstuvwxyz", font=font, fill=0)
draw.text((0, 112), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", font=font, fill=0)
draw.text((0, 142), "1234567890" + " ", font=font, fill=0)
draw.text((0, 172), "!\"#$%&'()=~|+*<>?_{}" + " ", font=font, fill=0)
p = Usb(0x0416, 0x5011, 0, 0x81, 0x03)
p.text("Hello World\n")
p.image(image)
p.cut()
こちらを印刷したものが下記のようになります。
※ p.text("Hello World\n")
でテキストを実行する場合、最初の位置文字が消えるので、気をつけてください。
USBの設定
レシートプリンターで印刷する場合は、こちらを設定する必要があります。
それについて、確認していきます。
p = Usb(0x0416, 0x5011, 0, 0x81, 0x03)
まずは、lsusbを実行しましょう
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 006: ID 8087:07dc Intel Corp.
Bus 001 Device 005: ID 0bda:579a Realtek Semiconductor Corp.
Bus 001 Device 004: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller
Bus 001 Device 003: ID 0bda:b812 Realtek Semiconductor Corp.
Bus 001 Device 008: ID 0416:5011 Winbond Electronics Corp. Virtual Com Port
Bus 001 Device 002: ID 062a:4102 Creative Labs
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
下記のものがレシートプリンターに接続されているものです。
Bus 001 Device 008: ID 0416:5011 Winbond Electronicのs Corp. Virtual Com Port
この0416:5011
の部分がUsb引数の1つめと、2つめとなります。
これだけでもsudoをつけて、root権限でpythonを実行すれば、印刷ができます。
このときに、一般ユーザーからもこのデバイスにアクセスできるように udev にルールを追加して、udev のルールを読み込ませてやります。
※udev
簡単に説明するとUSBデバイスを抜き差ししても、このUSBが何かを管理してくれるものです。(正確にはリンクで確認してください。)
udevの設定
/etc/udev/rules.d/10-printer.rulesファイルを作成し、下記を記載します。
先のlsusbで デバイスID: 0416: 5011
が異なる場合には、こちらも合わせてください。
SUBSYSTEM=="usb", ATTR{idVendor}=="0416", ATTR{idProduct}=="5011", MODE="0666", GROUP="plugdev"
2. 設定とコーディング2
指定の画像をロゴごとして追加して印刷する
下記の画像を先程作成したデータに追加して印刷する。
from escpos.printer import Usb
from escpos import *
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
# レシートプリンターを使った印刷
width = 500
height = 400
image = Image.new('1', (width, height), 255)
draw = ImageDraw.Draw(image)
font = ImageFont.truetype('FLOPDesignFont.ttf', 50, encoding='unic')
draw.text((0, 100), "日本語" + " ", font=font, fill=0)
font = ImageFont.truetype('storage/font/FLOPDesignFont.ttf', 28, encoding='unic')
draw.text((0, 182), "abcdefghijklmnopqrstuvwxyz", font=font, fill=0)
draw.text((0, 212), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", font=font, fill=0)
draw.text((0, 242), "1234567890" + " ", font=font, fill=0)
draw.text((0, 272), "!\"#$%&'()=~|+*<>?_{}" + " ", font=font, fill=0)
logo = Image.open('qiita-logo.png')
image.paste(logo, (150, 10))
# image.show()
p = Usb(0x0416, 0x5011, 0, 0x81, 0x03)
p.text(" \n")
p.image(image)
p.cut()
まとめ
これで、テキストや簡単な画像をレシートプリンターで印刷できるようになりました。
ちなみに今回レシートプリンターを選択したのは、単純に金額が安価なためです。レシートプリンターが4500円/ レジペーパーも5個で900円程度ですしね!