2次元ではなく1次元バーコードの仕組みを調べてみた
はじめに
私はカロリーメイトが好きで常備しているんですが、今日、仕事中にふと側面の(1次元)バーコードに目が止まりました。

昨今では、QRコードをはじめとする2次元バーコードばかりが取り沙汰されていますね。
1次元バーコードについての技術面が語られる機会は聞いたことがなかった。
ということで、改めて1次元バーコードの理解を深めるため、日本の食品に広く使われているJANコードの仕様から、画像を読み取ってデコードするまでの処理フローを調べた結果を整理したいと思いました。
日本の食品についているバーコード
JANコード
日本の一般的な食料品には、 JANコード(Japanese Article Number) が使用されているそうです。これは国際標準である EAN-13(European Article Number) と互換性がある一次元バーコード。
基本仕様:
- 規格名: JIS X 0501(EAN/UPC互換)
- 構成: 13桁の数字
- 例:
4901234567894

上記の図は、JANコードの構造を示している。13桁の数字列は4つの要素に分解される。
バーコードを読み取る仕組み
「画像から一次元バーコード(JAN/EAN-13)を読む」処理は、以下の6ステップで構成される。

生成AIで作った図なので少し雑ですが、ご容赦ください。
ステップ1: 画像入力・前処理
カメラやスキャナから画像を取得し、以下の前処理を施す:
- グレースケール化: カラー情報を輝度に変換
- 平滑化: ガウシアンフィルタでノイズを低減
- コントラスト強調: 明暗差を明確化
- 二値化: バーとスペースを黒/白に分離
スマートフォンアプリでは、ガイド枠の表示やオートフォーカスの調整により、撮影品質を向上させている。
ステップ2: バーコード領域検出
画像全体から「バーコードらしい部分」を探す。主な手法:
- エッジ検出: Sobelフィルタで平行な縦線が密集した領域を抽出
- 投影プロファイル: 横方向スキャンで明暗の周期的変化を検出
- 形状判定: 細長い長方形で縦線が多い領域を候補に
複数候補がある場合、コントラスト・線の整列度・アスペクト比などでスコアリングし、最適な領域を選択する。
ステップ3: 姿勢・歪み補正
撮影角度によるバーコードの斜めや台形歪みを補正する。
- 回転補正: バーの向きを推定し、垂直/水平に回転
- 射影変換: 4頂点を推定し、正面から見た長方形に変換
ステップ4: バー・スペースパターン抽出
補正済み画像から1次元の明暗パターンを抽出する。
処理フロー:
- 画像中央の水平ラインをスキャン
- ピクセルの輝度を取得
- しきい値処理で黒/白に分類
- 連続する黒=バー幅、白=スペース幅として測定
全体の幅から「最小モジュール幅」を推定し、各バー/スペースを正規化する。これにより、「バー幅・スペース幅のシーケンス」が得られる。
ステップ5: 規格に従ったデコード(EAN-13の場合)
ガードパターンの検出
EAN-13は以下の固定パターンで構成される:

ガードパターンを起点として、開始・中央・終了位置を特定する。
数字への変換
1桁ごとに7モジュールのパターンが割り当てられている。左側6桁は偶数/奇数パリティ付き、右側6桁は別パターンを使用。
各バー/スペース配列をパターン表と照合し、「0〜9」の数字に変換する。左側6桁のパリティ組み合わせから先頭桁を決定し、13桁の数字列を得る。
ステップ6: チェックディジット検証と結果出力
EAN-13では以下の式でチェックディジットを計算する:
チェックディジット = 10 - ((奇数桁合計 + 3 × 偶数桁合計) mod 10)
計算結果と13桁目が一致すれば「正しく読めた」と判定し、コード値をアプリケーションに渡す。不一致の場合は、別のスキャンラインで再デコードする。
実例: カロリーメイトのバーコード
ここでは、大塚製薬の「カロリーメイト ブロック」を例に、実際のバーコードデコード処理を見る。
バーコード情報
-
コード:
4987035648918 -
国コード:
49(日本) -
メーカーコード:
4987035(大塚製薬株式会社) -
商品コード:
64891 -
チェックディジット:
8
チェックディジット計算の実例
実際に 4987035648918 のチェックディジットを計算してみる。
計算手順:
-
奇数桁の合計(左から1, 3, 5, 7, 9, 11桁目):
4 + 8 + 0 + 5 + 4 + 9 = 30 -
偶数桁の合計(左から2, 4, 6, 8, 10, 12桁目):
9 + 7 + 3 + 6 + 8 + 1 = 34 -
チェックディジット計算:
(30 + 3 × 34) = 30 + 102 = 132 132 mod 10 = 2 10 - 2 = 8 -
検証結果:
- 計算結果:
8 - 実際の13桁目:
8 - 一致 → 検証OK ✓
- 計算結果:
メーカーコードは誰が決めてるの?
GS1 Japanが決めてる
JANコードの事業者コード(例: 4987035)は、 GS1 Japan(一般財団法人流通システム開発センター) が管理・付与している。
GS1 Japanは日本国内でのバーコード識別番号(JAN企業コード)の発行機関であり、国際機関GS1本部(ベルギー)の管理下で運営されている。企業ごとに「事業者コード(Company Prefix)」を登録し、その範囲内で企業が独自に商品コードを付与するそうだ。
コード体系の構造
日本のJANコード(13桁)は以下のように構成される:
| 区分 | 桁数 | 内容 | 管理主体 |
|---|---|---|---|
| 国コード | 2桁 | 国識別(49, 45など) | GS1本部 |
| 事業者コード | 4〜7桁 | 企業識別 | GS1 Japan |
| 商品コード | 3〜6桁 | 商品識別 | 各企業 |
| チェックディジット | 1桁 | 検証用 | 自動算出 |
カロリーメイトの例:
- 国コード:
49(日本) - 事業者コード:
87035(大塚製薬) - 商品コード:
6489 - チェックディジット:
8
事業者コードの桁数
事業者コードの桁数は、登録時の企業の登録商品数によって異なる:
- 短いコード(4桁): 登録範囲が広い大企業向け
- 長いコード(7桁): 登録範囲が狭い小規模企業向け
まとめ
本記事では、日本の食品に広く使われている一次元バーコード「JANコード」について、ふとした疑問から調査を行いました。ゼロからのプログラム実装もそこまで難しくなさそうですし、書いてみても面白いかもしれませんね。
Discussion