pythonで一次元バーコードを作成する

pythonで一次元バーコードを作成するには、python-barcodeが便利なようです。作成方法を調べてみましたが、日本語で説明しているページがあまりなかったので、

https://pypi.org/project/python-barcode/

を参考にしました。

python-barcodeのインストール

SVGファイルだけでいい場合

pip install python-barcode

画像(PNG)で作成する場合

pip install python-barcode
pip install pillow

もしくは、

pip install "python-barcode[images]"

これは、どちらでもインストールするものは同じみたいです。要するに、python-barcodepillowをインストールします。

バーコード画像を作成するには、pillowも必要だということです。

SVGとは

よく分からないので、要点だけ。

SVGは、Scalable Vector Graphicsの略で、ベクタ形式の画像。

GIF、JPEG、PNGは、ラスタ形式(ビットマップ形式)。

SVGの特徴

  • ベクタ形式
  • XMLで記述
  • 拡大縮小しても劣化しない
  • CSSやjavascriptでアニメーションを作ることができる

作成できるバーコードのタイプ

  • EAN-8
  • EAN-13
  • EAN-14
  • UPC-A
  • JAN
  • ISBN-10
  • ISBN-13
  • ISSN
  • Code 39
  • Code 128
  • PZN
>>> import barcode
>>> barcode.PROVIDED_BARCODES
['code128', 'code39', 'ean', 'ean13', 'ean14', 'ean8', 'gs1', 'gs1_128', 'gtin', 'isbn', 'isbn10', 'isbn13', 'issn', 'itf', 'jan', 'pzn', 'upc', 'upca']

バーコードの規格等、バーコードについての詳しい情報はキーエンスのHPにのっています。

バーコード講座 キーエンス:https://www.keyence.co.jp/ss/products/autoid/codereader/

SVGで作成

バーコードのタイプは【EAN-13】です。

import barcode

EAN = barcode.get_barcode_class('ean13')

ean = EAN('5901234123457')

ean.save('ean13_barcode')
ean13_barcode.svg
5901234123457
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg
  PUBLIC '-//W3C//DTD SVG 1.1//EN'
  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="44.000mm" height="23.000mm">
    <!--Autogenerated with python-barcode 0.13.1-->
    <g id="barcode_group">
        <rect width="100%" height="100%" style="fill:white"/>
        <rect x="6.500mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="6.830mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="7.160mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="7.490mm" y="1.000mm" width="0.990mm" height="15.000mm" style="fill:white;"/>
        <rect x="8.480mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="8.810mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="9.140mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="9.800mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="10.130mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="10.460mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="11.120mm" y="1.000mm" width="0.990mm" height="15.000mm" style="fill:black;"/>
        <rect x="12.110mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="12.440mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="13.100mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="13.760mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="14.420mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="15.080mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="15.410mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="16.070mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="16.730mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="17.060mm" y="1.000mm" width="1.320mm" height="15.000mm" style="fill:black;"/>
        <rect x="18.380mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="18.710mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="19.040mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="19.700mm" y="1.000mm" width="0.990mm" height="15.000mm" style="fill:black;"/>
        <rect x="20.690mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="21.020mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="21.350mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="21.680mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="22.010mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="22.340mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="22.670mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="23.000mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="23.660mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="24.320mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="24.980mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="25.310mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="25.970mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="26.300mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:black;"/>
        <rect x="26.960mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="27.620mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="27.950mm" y="1.000mm" width="1.320mm" height="15.000mm" style="fill:white;"/>
        <rect x="29.270mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="29.600mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="29.930mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="30.260mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="30.590mm" y="1.000mm" width="0.990mm" height="15.000mm" style="fill:black;"/>
        <rect x="31.580mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="32.240mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="32.570mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="33.230mm" y="1.000mm" width="0.990mm" height="15.000mm" style="fill:black;"/>
        <rect x="34.220mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="34.550mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="34.880mm" y="1.000mm" width="0.990mm" height="15.000mm" style="fill:white;"/>
        <rect x="35.870mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="36.200mm" y="1.000mm" width="0.660mm" height="15.000mm" style="fill:white;"/>
        <rect x="36.860mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <rect x="37.190mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:white;"/>
        <rect x="37.520mm" y="1.000mm" width="0.330mm" height="15.000mm" style="fill:black;"/>
        <text x="22.175mm" y="21.000mm" style="fill:black;font-size:10pt;text-anchor:middle;">5901234123457</text>
    </g>
</svg>

PNGで作成

バーコードのタイプは【EAN-13】です。

import barcode
from barcode.writer import ImageWriter

EAN = barcode.get_barcode_class('ean13')

ean = EAN('5901234123457', writer=ImageWriter())

ean.save('ean13_barcode')
ean13_barcode.png

JPEGでは作成できない?

https://pypi.org/project/python-barcode/には、以下のコードがのっていましたので、作成してみると、

from barcode import EAN13
from barcode.writer import ImageWriter

with open('somefile.jpeg', 'wb') as f:
    EAN13('100000011111', writer=ImageWriter()).write(f)
somefile.jpeg

拡張子はJPEGなのですが、バイナリエディタでのぞいてみると中身はPNGになっています。

調べてみましたが、結局、PNG以外の画像を作成する方法はわかりませんでした。

しかし、SVGとPNGで作成できれば、特に問題はないと思っています。

SVGのことはよく知らなかったのですが、HTMLに埋め込むのと編集するのが楽になるみたいですね。

その後、ドキュメント(https://python-barcode.readthedocs.io/en/stable/)を読んでいると、JPEGでの作成方法が分かりました。

JPEGで作成

ImageWriter()で、format=’JPEG’を指定します。

import barcode
from barcode.writer import ImageWriter

EAN = barcode.get_barcode_class('ean13')

ean = EAN('5901234123457', writer=ImageWriter(format='JPEG'))

ean.save('ean13_barcode')

Options設定

https://python-barcode.readthedocs.io/en/stable/writers/index.html#common-writer-optionsに設定できる項目がのっていました。

Common Options

module_width:The width of one barcode module in mm as float. Defaults to 0.2.
module_height:The height of the barcode modules in mm as float. Defaults to 15.0.
quiet_zone:Distance on the left and on the right from the border to the first (last) barcode module in mm as float. Defaults to 6.5.
font_path:Path to the font file to be used. Defaults to DejaVuSansMono (which is bundled with this package).
font_size:Font size of the text under the barcode in pt as integer. Defaults to 10.
text_distance:Distance between the barcode and the text under it in mm as float. Defaults to 5.0.
background:The background color of the created barcode as string. Defaults to white.
foreground:The foreground and text color of the created barcode as string. Defaults to black.

New in version 0.6.

center_text:If true (the default) the text is centered under the barcode else left aligned.

辞書型で指定

オプションの設定は、辞書型で指定します。

import barcode
from barcode.writer import ImageWriter
EAN = barcode.get_barcode_class('ean13')
ean = EAN('5901234123457', writer=ImageWriter())
ean.save('orange_barcode', {'background':'orange', 'module_width':0.5})

または、

import barcode
from barcode.writer import ImageWriter
EAN = barcode.get_barcode_class('ean13')
ean = EAN('5901234123457', writer=ImageWriter())
options = dict(background='orange', module_width=0.5)
ean.save('orange_barcode', options)
orange_barcode.png

SVGでもオプションを設定できます。

import barcode
EAN = barcode.get_barcode_class('ean13')
ean = EAN('5901234123457')
ean.save('orange_barcode', {'background':'orange', 'module_width':0.5})
orange_barcode.svg
5901234123457