Python を使って一次元のバーコード作成ソフトウェアを作ります。
以下の環境で動作確認をしています。
環境: Windows パソコン、Python 3.x
背景: 一次元のバーコード作成ソフト!
以前に、Python を使って、QR コードを作成するソフトウェアを作っています(下記の関連リンク参照)。
そこで今回は、一般の一次元のバーコード作成ソフトウェアを作ってみます。実質的に、オープンソースで無料のバーコード作成アプリです。
バーコードを読み取るプログラムについても、以前に、すでに作成しています。
一次元バーコードの作成ができるようになると、任意の文字列について一次元バーコードや QR コードを作り、Windows パソコンなどに接続した USB カメラでバーコードを読み取るなど、自由自在に活用できることになります。
対応するバーコードは現在のところ、Code128、Code39、JAN、EAN13、EAN8、UPC-A、ISBN(標準タイプのみ)です。Python 等がインストールされていれば、コピー&ペースト程度で動くということになります。
python-barcode のインストール
バーコードの作成にあたり、パッケージ python-barcode が必要です。
インストールしていない場合は、Windows パソコンのコマンドプロンプト(または、Anaconda prompt)を起動し、以下のコマンドで、インストールをしてください。
pip install python-barcode
※ なお、python-barcode がインストールしてあるかどうか確認するには、”pip list | findstr bar” 等とすると、すでにインストールされていて、文字列 “bar” を含むパッケージの一覧が表示されると思います。
サンプルスクリプトの設定
① パソコン内にフォルダを作成してください。
例: C:\user\barcode1
② 上記のフォルダに barcode_generator1.py 等の名前でテキストファイルを作成し、下記のサンプルスクリプトをコピー&ペーストして保存してください。
使い方
③ Windows パソコンのコマンドプロンプトを起動して、上記のスクリプトを実行してください。
例: python c:\user\barcode1\barcode_generator1.py
④ 上の画像のように、作成したいバーコードの種別(Code128等)を選択し、barcode_data の欄に文字列を入力してください。
⑤ 「encode」ボタンをクリックしてください。バーコードを作成します。
パソコンの[enter]キーでも動きます。
⑥ バーコードが作成できたら、「copy」ボタンをクリックして、Excel 等の上で「貼り付け」を実行することで、他のアプリで使用することができます。
⑦ バーコードを保存するには、表示画面で保存するファイル名を入力し、「save」ボタンをクリックします。画像は、①のフォルダに保存されます。
※ なお、バーコードの仕様としては、Code128、Code39 では、任意の文字数の英数字に対応しています。EAN13 は、13桁の数字のみ対応(末尾の1桁はチェックデジット)となっています。JAN は、49、45 から始まる13桁の数値です。ISBN は同様に 978、979 から始まる 13桁の数値です。
文字列を入力した際、バーコードの仕様上、バーコードが作成できない場合は、プログラム内でチェックし、はじくようにしています。
スクリプトの説明
・ 冒頭で、必要なパッケージ等をインポートしています。
GUI の作成のため、tkinter、tkinter.ttk をインポートしています。
import barcode とした行で、上記でインストールした python-barcode をインポートしています。
作成したバーコード画像の表示のため、PIL 等をインポートしています。
win32cclipboard は、作成したバーコード画像をクリップボードにコピーするためのものです。
・ clear1() は、画像領域をクリアするための関数です。
・ check_string1() で、入力した文字列をバーコード画像に変換できるか事前にチェックしています。バーコードの仕様から、変換ができない場合は、data1 = “” を返すようにして、バーコードを作成しないようにしています。
入力データをより厳密にチェックしたい場合は/入力データに制約を加えたい場合は、この部分を修正してください。
・ encode1() が、バーコードを作成するメインの関数です。
エンコードしたいバーコードの種別から、対応するクラス(class1)を取得します。このクラスにバーコードデータを入力することで、バーコードのオブジェクト(barcode1)を作成します。
バーコードのオブジェクト barcode1 から画像を取得し、Tkinter で表示可能な画像フォーマットに変換し、label3.config に入れることでバーコードの画像を表示しています。
バーコードのデータが長いと、画像も横長になります。そこで、画像の幅 width1 を適宜設定することで、表示領域を調整しています。
・ enter1(event1)、selected1(event1)は、後述の Tkinter のオブジェクトをユーザが操作したときに実行するイベントの処理です。
・ save1() は、画面のボタン「save」をクリックしたときに実行する処理です。画面上、入力されているファイル名でスクリプトのある同一フォルダ内に画像を保存します。
・ copy1() は、画面のボタン「copy」をクリックしたときに実行する処理です。
Windows のクリップボードの処理を呼び出しています。Windows 以外の OS を使いたい場合は、この部分を削除して、必要な修正をしてください。
・ path1 = … とした行以降が、Python のスクリプトを実行したときに行われる処理です。
・ frame1 = … としたところで画面を作成しています。
その画面に、ラベル、テキストボックス、ボタン、コンボボックス等を配置しています。
・ テキストボックス内で「enter」キーを押したときにバーコードを作成したいので、textbox1.bind( … ) として、イベントに紐づけて上記の関数 enter1() を実行するよう設定しています。
・ また、コンボボックス(ドロップダウンリスト)で、バーコードの種別を選択したときにもバーコードが作成されるようにしたいので、同様に関数 selected1() を実行するように設定しています。
まとめ
1次元のバーコードについても自由に作成できるようになりました。
なお、今回のスクリプトと同様にQRコードを作成することも可能です。
もし、Web カメラをお持ちでしたら、パソコンに Web カメラを接続し、今回作成したバーコードを読み取ることも可能です。バーコードの作成、および、読み取りの両方に対応した自動化のシステムを構築できることになります。
また、Wi-Fi などローカルネットワークの環境が使えるようでしたら、ローカルネットワーク内で今回のプログラムを Web アプリ化することも可能です。
もし関心があるようでしたら、以下の関連リンクも参照してみてください。
関連リンク
・ バーコードリーダ 【QRコード対応】
・ 動作確認済み USB カメラ 【おすすめ】
・ QRコード作成ソフトウェア 【Python】
・ バーコードリーダ Web アプリ 【Raspberry Pi & Flask】
・ バーコード作成 Web アプリ 【Raspberry Pi & Flask】
・ Python カレンダー 【tkinter】
外部リンク
・ python-barcode Getting started
サンプルスクリプト
バーコード作成ソフトウェア barcode_generator1.py
#!/usr/bin/env python
# -*- coding: utf8 -*-
#
# pip install python_barcode
#
import os
import tkinter as tk1
import tkinter.ttk as ttk1
import barcode as bc1
from barcode.writer import ImageWriter
import io
from PIL import Image, ImageTk, ImageGrab
import win32clipboard as wc1 # for Windows
def clear1():
label3.config( image="" )
return ""
def check_string1():
type1 = option1[combo1.current()].replace("-", "").lower()
type2 = type1.replace("jan", "ean13").replace("isbn", "ean13")
data1 = textbox1.get()
str1 = ""
if type2 == "ean13":
if data1.isdigit() == False:
data1 = ""
str1 = "EAN13 can only contain numbers. "
elif len(data1) < 12:
data1 = ""
str1 = "EAN13 must have 12 digits. "
elif type1 == "isbn":
if data1[0:3] != "978" and data1[0:3] != "979":
data1 = ""
str1 = "ISBN must start with 978 or 979. "
elif type1 == "jan":
if data1[0:2] != "45" and data1[0:2] != "49":
data1 = ""
str1 = "JAN must start with 45 or 49. "
elif type2 == "ean8":
if data1.isdigit() == False:
data1 = ""
str1 = "EAN8 can only contain numbers. "
elif len(data1) < 7 :
data1 = ""
str1 = "EAN8 must have 7 digits. "
elif type2 == "upca":
if data1.isdigit() == False:
data1 = ""
str1 = "UPC can only contain numbers. "
elif len(data1) < 11:
data1 = ""
str1 = "UPC must have 11 digits. "
print( data1 + " " + type1 )
print( str1 )
return data1, type1
def encode1():
global barcode1, img1
global option1
global w1, h1
clear1()
data1, type1 = check_string1()
if data1 != "":
class1 = bc1.get_barcode_class( type1 )
barcode1 = class1( data1, writer=ImageWriter() )
img1 = ImageTk.PhotoImage( barcode1.render() )
width1 = img1.width()
if width1 < 650:
width1 = 650
label3.config( image = img1 )
label3.place( width = width1 )
w1 = width1 + 50
frame1.geometry( f"{w1}x{h1}" )
def enter1( event1 ):
encode1()
def selected1( event1 ):
encode1()
def save1():
global path1
file1 = path1 + str( textbox2.get() )
print( file1 )
with open(file1, "wb") as f1:
barcode1.write( f1 )
def copy1():
global barcode1
buf1 = io.BytesIO()
barcode1.write(buf1)
buf1.seek(0)
img1 = Image.open(buf1)
img1.convert("RGB")
output1 = io.BytesIO()
img1.save(output1, "BMP")
data1 = output1.getvalue()[14:]
output1.close()
wc1.OpenClipboard()
wc1.EmptyClipboard()
wc1.SetClipboardData(wc1.CF_DIB, data1)
wc1.CloseClipboard()
return
path1 = os.path.dirname(__file__) + "\\"
img1 = 0
barcode1 = 0
w1 = 700
h1 = 400
frame1 = tk1.Tk()
frame1.title(u"barcode_generator v0.1")
frame1.geometry( f"{w1}x{h1}")
label1 = tk1.Label(text='barcode data', anchor='w')
label1.place(x=10, y=10, width=100)
label2 = tk1.Label(text='file name', anchor='w')
label2.place(x=10, y=40, width=100)
label3 = tk1.Label( frame1, bg='white' )
label3.place(x=25, y=70, width = 650, height = 300)
textbox1 = tk1.Entry( master=frame1 )
textbox1.place(x=100, y=10, width=200)
textbox1.bind("<Return>", enter1 )
textbox2 = tk1.Entry( master=frame1 )
textbox2.place(x=100, y=40, width=200)
textbox2.delete( 0, tk1.END )
textbox2.insert( 0, "file01.png" )
button1 = tk1.Button( frame1, text='encode', command=encode1 )
button1.place(x=320, y=5, width=100)
button2 = tk1.Button( frame1, text='save', command=save1 )
button2.place(x=320, y=35, width=100)
button3 = tk1.Button( frame1, text='clear', command=clear1 )
button3.place(x=430, y=5, width=100)
button4 = tk1.Button( frame1, text='copy', command=copy1 )
button4.place(x=430, y=35, width=100)
option1 = ["code128", "code39", "EAN13", "EAN8", "JAN", "UPC-A", "ISBN"]
combo1 = ttk1.Combobox( frame1, values=option1, state="readonly" )
combo1.current(0)
combo1.place( x=540, y=5, width=100)
combo1.bind( "<<ComboboxSelected>>", selected1 )
frame1.mainloop()