Skip to content

Commit f453138

Browse files
authored
Merge pull request #368 from Integration-Automation/feat/barcode-batch
Add 1-D barcode decoding (read_barcodes)
2 parents 50af1c3 + 687b40a commit f453138

15 files changed

Lines changed: 256 additions & 1 deletion

File tree

README/WHATS_NEW_zh-CN.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-23) — 一维条码解码
4+
5+
从屏幕或图像读取 EAN / UPC / Code-128 条码。完整参考:[`docs/source/Zh/doc/new_features/v157_features_doc.rst`](../docs/source/Zh/doc/new_features/v157_features_doc.rst)
6+
7+
- **`read_barcodes`**(`AC_read_barcodes`):框架已能解码 QR Code(`read_qr`),但缺少能读取*一维*条码(EAN-13/8、UPC-A、Code-128)的功能——这些正是商品、库存标签与物流面单上最常见的条码。本功能通过 OpenCV 的 `cv2.barcode.BarcodeDetector` 解码,每个条码返回 `{text, type, points}`。解码步骤为可注入接缝(默认调用 OpenCV;测试可传入自己的 `decoder`),因此可完整无头测试且能优雅降级——若 OpenCV 编译时未含 `barcode` 模块,返回 `[]` 而非抛出异常。重用共用的 `visual_match` haystack 加载器;不导入 `PySide6`
8+
39
## 本次更新 (2026-06-23) — 加权候选评分
410

511
以信心分数排序模棱两可的元素候选。完整参考:[`docs/source/Zh/doc/new_features/v156_features_doc.rst`](../docs/source/Zh/doc/new_features/v156_features_doc.rst)

README/WHATS_NEW_zh-TW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# 本次更新 — AutoControl
22

3+
## 本次更新 (2026-06-23) — 一維條碼解碼
4+
5+
從螢幕或影像讀取 EAN / UPC / Code-128 條碼。完整參考:[`docs/source/Zh/doc/new_features/v157_features_doc.rst`](../docs/source/Zh/doc/new_features/v157_features_doc.rst)
6+
7+
- **`read_barcodes`**(`AC_read_barcodes`):框架已能解碼 QR Code(`read_qr`),但缺少能讀取*一維*條碼(EAN-13/8、UPC-A、Code-128)的功能——這些正是商品、庫存標籤與物流面單上最常見的條碼。本功能透過 OpenCV 的 `cv2.barcode.BarcodeDetector` 解碼,每個條碼回傳 `{text, type, points}`。解碼步驟為可注入接縫(預設呼叫 OpenCV;測試可傳入自己的 `decoder`),因此可完整無頭測試且能優雅降級——若 OpenCV 編譯時未含 `barcode` 模組,回傳 `[]` 而非拋出例外。重用共用的 `visual_match` haystack 載入器;不匯入 `PySide6`
8+
39
## 本次更新 (2026-06-23) — 加權候選評分
410

511
以信心分數排序模稜兩可的元素候選。完整參考:[`docs/source/Zh/doc/new_features/v156_features_doc.rst`](../docs/source/Zh/doc/new_features/v156_features_doc.rst)

WHATS_NEW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# What's New — AutoControl
22

3+
## What's new (2026-06-23) — Barcode Decoding (1-D)
4+
5+
Read EAN / UPC / Code-128 barcodes off the screen or an image. Full reference: [`docs/source/Eng/doc/new_features/v157_features_doc.rst`](docs/source/Eng/doc/new_features/v157_features_doc.rst).
6+
7+
- **`read_barcodes`** (`AC_read_barcodes`): the framework decoded QR codes (`read_qr`) but had no reader for the *1-D* barcodes (EAN-13/8, UPC-A, Code-128) that label physical goods, inventory tickets and shipping labels. This decodes them via OpenCV's `cv2.barcode.BarcodeDetector`, returning `{text, type, points}` per code. The decode step is an injectable seam (default calls OpenCV; tests pass their own `decoder`), so it's fully headless-testable and degrades gracefully — an OpenCV build without the `barcode` module returns `[]` instead of raising. Reuses the shared `visual_match` haystack loader; no `PySide6`.
8+
39
## What's new (2026-06-23) — Weighted Candidate Scoring
410

511
Rank ambiguous element candidates by a confidence score. Full reference: [`docs/source/Eng/doc/new_features/v156_features_doc.rst`](docs/source/Eng/doc/new_features/v156_features_doc.rst).
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
Barcode Decoding (1-D)
2+
======================
3+
4+
The framework already decodes QR codes (``read_qr``), but had no reader for the
5+
*1-D* barcodes (EAN-13 / EAN-8 / UPC-A / Code-128) that label physical goods,
6+
inventory tickets and shipping labels — the most common thing a desktop or kiosk
7+
automation needs to read off a product screen. ``read_barcodes`` fills that gap
8+
using OpenCV's ``cv2.barcode.BarcodeDetector``.
9+
10+
The decode step is an **injectable seam**: the default decoder calls OpenCV, but
11+
tests (and alternative engines) can pass their own ``decoder`` callable, so the
12+
feature is fully unit-testable headlessly and degrades gracefully — a build of
13+
OpenCV without the ``barcode`` module simply returns an empty list instead of
14+
raising. Imports no ``PySide6``.
15+
16+
Headless API
17+
------------
18+
19+
.. code-block:: python
20+
21+
from je_auto_control import read_barcodes
22+
23+
# decode every 1-D barcode currently on screen
24+
for code in read_barcodes():
25+
print(code["type"], code["text"], code["points"])
26+
27+
# restrict to a region, or decode a saved image instead of the screen
28+
read_barcodes(region=[0, 0, 400, 200])
29+
read_barcodes("label.png")
30+
31+
``read_barcodes(source=None, *, region=None, decoder=None)`` returns a list of
32+
``{"text", "type", "points"}`` dicts, one per detected barcode (``points`` is the
33+
four-corner polygon in image coordinates). ``source`` may be an image path or an
34+
array; when omitted the screen (optionally cropped to ``region``) is grabbed. The
35+
grayscale conversion reuses the shared ``visual_match`` haystack loader, so no new
36+
image-loading code is added.
37+
38+
Executor command
39+
----------------
40+
41+
``AC_read_barcodes`` (``source`` / ``region`` → ``{count, barcodes}``) is exposed
42+
as the MCP tool ``ac_read_barcodes`` (read-only) and as a Script Builder command
43+
**Read Barcodes (1-D)** under **OCR**.

docs/source/Eng/eng_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ Comprehensive guides for all AutoControl features.
179179
doc/new_features/v154_features_doc
180180
doc/new_features/v155_features_doc
181181
doc/new_features/v156_features_doc
182+
doc/new_features/v157_features_doc
182183
doc/ocr_backends/ocr_backends_doc
183184
doc/observability/observability_doc
184185
doc/operations_layer/operations_layer_doc
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
一維條碼解碼
2+
============
3+
4+
框架已能解碼 QR Code(``read_qr``),但缺少能讀取 *一維* 條碼(EAN-13 / EAN-8 /
5+
UPC-A / Code-128)的功能——這些正是商品、庫存標籤與物流面單上最常見的條碼,也是
6+
桌面或自助機自動化最需要從商品畫面讀取的資訊。``read_barcodes`` 透過 OpenCV 的
7+
``cv2.barcode.BarcodeDetector`` 補上這一塊。
8+
9+
解碼步驟是一個**可注入接縫**:預設解碼器呼叫 OpenCV,但測試(或其他引擎)可以傳入
10+
自己的 ``decoder`` 可呼叫物件,因此此功能可在無頭環境下完整單元測試,且能優雅降級
11+
——若 OpenCV 編譯時未含 ``barcode`` 模組,僅回傳空清單而非拋出例外。不匯入
12+
``PySide6``。
13+
14+
無頭 API
15+
--------
16+
17+
.. code-block:: python
18+
19+
from je_auto_control import read_barcodes
20+
21+
# 解碼螢幕上目前所有一維條碼
22+
for code in read_barcodes():
23+
print(code["type"], code["text"], code["points"])
24+
25+
# 限定區域,或改為解碼已存檔的影像
26+
read_barcodes(region=[0, 0, 400, 200])
27+
read_barcodes("label.png")
28+
29+
``read_barcodes(source=None, *, region=None, decoder=None)`` 回傳
30+
``{"text", "type", "points"}`` 字典清單,每偵測到一個條碼一筆(``points`` 為影像
31+
座標中的四角多邊形)。``source`` 可為影像路徑或陣列;省略時擷取螢幕(可選擇以
32+
``region`` 裁切)。灰階轉換重用共用的 ``visual_match`` haystack 載入器,不新增
33+
影像載入程式碼。
34+
35+
執行器指令
36+
----------
37+
38+
``AC_read_barcodes``(``source`` / ``region`` → ``{count, barcodes}``)以 MCP 工具
39+
``ac_read_barcodes``(唯讀)及 Script Builder 指令 **Read Barcodes (1-D)**(位於
40+
**OCR** 分類下)形式提供。

docs/source/Zh/zh_index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ AutoControl 所有功能的完整使用指南。
179179
doc/new_features/v154_features_doc
180180
doc/new_features/v155_features_doc
181181
doc/new_features/v156_features_doc
182+
doc/new_features/v157_features_doc
182183
doc/ocr_backends/ocr_backends_doc
183184
doc/observability/observability_doc
184185
doc/operations_layer/operations_layer_doc

je_auto_control/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@
385385
from je_auto_control.utils.element_scoring import (
386386
ScoredCandidate, best_candidate, score_candidates,
387387
)
388+
# 1-D barcode decoding (EAN / UPC) with an injectable decoder seam
389+
from je_auto_control.utils.barcode import read_barcodes
388390
# CI workflow annotations (GitHub Actions)
389391
from je_auto_control.utils.ci_annotations import (
390392
emit_annotations, format_annotation,
@@ -1278,6 +1280,7 @@ def start_autocontrol_gui(*args, **kwargs):
12781280
"score_candidates",
12791281
"best_candidate",
12801282
"ScoredCandidate",
1283+
"read_barcodes",
12811284
"emit_annotations", "format_annotation",
12821285
"ClipboardHistory", "default_clipboard_history",
12831286
"analyze_heal_log", "heal_stats", "scan_secrets",

je_auto_control/gui/script_builder/command_schema.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,15 @@ def _add_ocr_specs(specs: List[CommandSpec]) -> None:
586586
),
587587
description="Decode QR codes in a screen region (OpenCV).",
588588
))
589+
specs.append(CommandSpec(
590+
"AC_read_barcodes", "OCR", "Read Barcodes (1-D)",
591+
fields=(
592+
FieldSpec("source", FieldType.FILE_PATH, optional=True),
593+
FieldSpec("region", FieldType.STRING, optional=True,
594+
placeholder=_REGION_PLACEHOLDER),
595+
),
596+
description="Decode 1-D barcodes (EAN / UPC) in an image / screen region.",
597+
))
589598
specs.append(CommandSpec(
590599
"AC_scroll_to_find", "OCR", "Scroll Until Visible",
591600
fields=(
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""1-D barcode decoding (EAN / UPC) with an injectable decoder seam."""
2+
from je_auto_control.utils.barcode.barcode import read_barcodes
3+
4+
__all__ = ["read_barcodes"]

0 commit comments

Comments
 (0)