Skip to main content

Tapirscan for Python

Scan Pillow images, NumPy arrays and PyTorch tensors with tapirscan.scan(image). Quick start · Functions · All arguments · Results

Installation

Python 3.10+ is required. Platform wheels bundle all four native modes. Registry publication is pending; until then, use the local build guide.

Quick start

Install tapirscan plus the image libraries you use. For these examples:

pip install tapirscan tifffile pillow torch

TIFF → NumPy array, using defaults:

import tifffile
import tapirscan

pixels = tifffile.imread("label.tif", key=0)  # NumPy array: first TIFF page
result = tapirscan.scan(pixels)
print(result.values)

This example assumes an 8-bit grayscale or RGB image. Defaults are Medium effort and EAN-13. No intermediate file or explicit scanner object is needed.

JPEG, with optional settings:

from PIL import Image
import tapirscan

with Image.open("label.jpg") as image:
    result = tapirscan.scan(image, mode="high", formats="1D")

for barcode in result:
    print(barcode.text, barcode.format, barcode.polygon)

formats="1D" enables all supported linear formats; "2D" and "all" are also available. Additional formats are experimental.

PyTorch tensor:

import torch

# Using the NumPy array from the TIFF example:
tensor = torch.from_numpy(pixels)
result = tapirscan.scan(tensor)
print(result.values)

GPU tensors and tensors with requires_grad=True work directly. Tapirscan detaches internally and transfers pixels to CPU; your tensor and its autograd graph are unchanged. Barcode decoding runs on CPU.

Moving from pyzbar or ZXing-C++

For a Pillow image or grayscale NumPy array, an EAN-13 values-only call changes like this:

# Before (pyzbar):
values = [barcode.data.decode("utf-8") for barcode in decode(image)]
# Before (zxing-cpp):
values = [barcode.text for barcode in zxingcpp.read_barcodes(image)]
# After (Tapirscan):
values = tapirscan.scan(image).values

The old calls assume their existing imports. Select your application's formats explicitly when it needs more than EAN13, for example formats=["EAN13", "Code128"]. Additional readers are experimental; verify coverage before replacing an existing scanner. API conventions are documented by pyzbar and ZXing-C++.

Existing assumption What to check when migrating
All formats enabled Tapirscan defaults to EAN13. Use explicit formats or a preset.
OpenCV BGR arrays Convert to RGB or grayscale; Tapirscan uses RGB luminance.
.data or .text Prefer .text; Tapirscan's .data is UTF-8 encoded text, not a general raw binary-payload API.
Format strings / enums Map to Tapirscan identifiers; names and types can differ.
Polygon / position Use .polygon or .rect; geometry need not match another reader's boundary.
Orientation / quality .orientation is None; .quality is not comparable to ZBar's score.
Reader-specific options Options such as pyzbar's symbols do not transfer unchanged.

Start by running both libraries on your own images and comparing missing values, wrong reads and runtime. Preserve separate copies of equal-value symbols when counting instances. Reuse a Scanner for repeated images. A matching function shape alone does not make this a drop-in replacement.

Functions

Single-image function

tapirscan.scan(
    image, width=None, height=None, *,
    mode="medium", library_dir=None,
    channels=1, stride=None, multiple=True, debug=False,
    include_regions=None, formats=None, layout="auto", value_range="auto",
)

Returns ScanResult. Creates and closes a scanner automatically, including on failure. image is required; all other arguments are optional. Arguments after * must be passed by keyword. width and height are only needed for raw buffers.

Reusable scanner

tapirscan.Scanner(mode="medium", *, formats=None, library_dir=None)
scanner.scan(
    image, width=None, height=None, *,
    channels=1, stride=None, multiple=True, debug=False,
    include_regions=None, formats=None, layout="auto", value_range="auto",
)
scanner.close()

Use it for successive images to avoid initialization on every call:

import tapirscan

with tapirscan.Scanner(mode="high", formats="1D") as scanner:
    for image in images:
        result = scanner.scan(image)
        print(result.values)

The context manager calls close() even on exceptions. You can instead call close() in a finally block; repeated close is safe. Results remain valid after closure. Calls on one scanner serialize; separate scanners can run concurrently. Create another scanner to change mode. Per-call formats override the constructor selection for that call only; None inherits it.

All arguments

Argument Default Accepted values and behavior
image Required Pillow image, NumPy array, PyTorch tensor, (pixels, width, height) grayscale tuple, or raw byte buffer with explicit dimensions.
mode "medium" "low", "medium", "high", "very-high". Constructor/module function only.
formats None Default EAN13; "1D", "2D", "all", or nonempty list/tuple of exact identifiers. On a reusable scanner, None inherits its selection.
library_dir None Path/string for custom native builds. Constructor/module function only.
width, height None Both required for raw buffers, inferred for image objects. Minimum 3 pixels each.
channels 1 Raw buffers only: 1 grayscale, 3 RGB, 4 RGBA. Alpha ignored.
stride None Raw buffers only: bytes between row starts; defaults to width * channels. Padding allowed.
multiple True False keeps only the highest-support read after scanning; no early exit.
debug False Include search diagnostics in result.debug. Polygons are always returned.
include_regions None Compatibility alias for debug; prefer debug in new code.
layout "auto" NumPy/tensors: "HW", "HWC", "CHW". Specify when channel position is ambiguous.
value_range "auto" NumPy/tensors: "0_1" or "0_255". Auto scales floats in [0,1]; otherwise values must fit [0,255].

Library lookup: explicit library_dir, then TAPIRSCAN_LIBRARY_DIR, then bundled wheel libraries. The working directory is never searched implicitly.

Formats and group exports: Format, FormatSelection, retail_formats, linear_formats, matrix_formats. See exact identifiers and reader limitations. Presets cover supported symbologies. Additional readers use fixed effort; the four effort modes tune the EAN13/UPCA path.

Array and tensor inputs

Accepts one HW/HWC/CHW image, optionally with a leading batch axis of size one, with 1/3/4 channels. NumPy views and noncontiguous tensors are accepted. Colors are RGB/RGBA, not OpenCV BGR. Booleans become black/white. NaN, infinity and out-of-range values are rejected; explicitly scale higher-bit-depth intensities and undo mean/std normalization. The input buffer limit is 128 MiB.

GPU tensors (including CUDA and MPS) and requires_grad=True tensors can be passed directly. The adapter detaches internally, copies to CPU as needed, and makes pixels contiguous without changing the input or its autograd graph. The scan is not differentiable and decoding does not run on GPU. Device transfer adds latency. Sparse, quantized, complex and meta tensors are rejected.

Results and public types

ScanResult is an immutable sequence: iterate, index, slice, use len(result) or check its truth value. Empty results are false.

Field/method Meaning
result.barcodes Tuple of immutable Barcode objects.
result.values Fresh list of decoded strings.
result.best Highest-support barcode, or None. Support is not a confidence probability.
result.image ImageSize(width, height) of supplied pixels.
result.mode, .multiple Applied effort and result-selection options.
result.elapsed_ms Native scanner time; excludes image conversion and result construction.
result.unfinished Incomplete scanning work; returned reads can still be useful.
result.debug Diagnostics, or None when not requested.
result.to_dict() Independent copy of the native schema-2 JSON, with requested diagnostics.
barcode.text, .format Decoded text and format identifier.
barcode.polygon Tuple of Point(x, y) source-image coordinates.
barcode.rect Enclosing integer Rect(left, top, width, height).

Coordinates start at the top left. The API returns geometry, not a cropped bitmap. If you resize before scanning, map coordinates back when drawing on the original. Other exported option types are Mode, Layout, ValueRange and ImageInput. The package includes py.typed for static type checkers.

Diagnostics

result = tapirscan.scan(image, debug=True)
if result.debug is not None and result.debug.regions is not None:
    print(result.debug.regions.proposals)
    print(result.debug.regions.search_windows)
    print(result.debug.regions.candidates)

Diagnostics also exposes barcodes (support, axis, candidate indices in result order), localization_limited and to_dict(). Region types are available in tapirscan.results. Reader-specific raw metadata, including GS1 and structured append, is retained in JSON. Evidence varies by reader. Candidate indices inside a recovery crop are local to that crop, not identifiers for tracking across frames.

Errors and migration helpers

Invalid input raises ValueError/TypeError; native errors raise ScannerError with a .code attribute. Scanning after close raises RuntimeError.

tapirscan.pyzbar.decode aliases tapirscan.scan. Barcode .data returns UTF-8 bytes, .type aliases format, .quality exposes the support heuristic, and .orientation is None. These ease migration but are not complete pyzbar compatibility; there is no symbols argument. Use the main API for new code.

Release files for tapirscan 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for tapirscan 1.0.0
File
tapirscan-1.0.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
tapirscan-1.0.0-py3-none-manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64 Details
tapirscan-1.0.0-py3-none-manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64 Details
tapirscan-1.0.0-py3-none-macosx_11_0_x86_64.whl Python 3 none macOS 11.0+ x86-64 Details
tapirscan-1.0.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details

Total release size: 24.6 MB

Release files / tapirscan-1.0.0-py3-none-win_amd64.whl

Download URL tapirscan-1.0.0-py3-none-win_amd64.whl
Size 4.6 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
795042cfb58c402b2b876405374a9b59db4fdc57a3886f09c3d3b1b0d2cd5103
BLAKE2b-256 checksum
How to use checksums
a4a1a7f564b7f90c10bb321758f064b32d8ac35967b230e5a91de246d1c7ec13
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / tapirscan-1.0.0-py3-none-manylinux_2_28_x86_64.whl

Download URL tapirscan-1.0.0-py3-none-manylinux_2_28_x86_64.whl
Size 5.4 MB
Tags Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
4c7d93b403171720e61fb3db3416ae622982e644bc2fd7b9a8877baccd1fee96
BLAKE2b-256 checksum
How to use checksums
2ee3d225ec6e04f541dba5bbd943e3313c67f832c44c78b5e581e718f1b95e1c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / tapirscan-1.0.0-py3-none-manylinux_2_28_aarch64.whl

Download URL tapirscan-1.0.0-py3-none-manylinux_2_28_aarch64.whl
Size 4.9 MB
Tags Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
2e0889e28287ff9c116a473546c17c3d00d3958b4f3465e2847870ff6770666c
BLAKE2b-256 checksum
How to use checksums
acfb52eb6b8bc8940a2331b5f360083a1578cd6eb12e12aff5a55194cd28f0c0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / tapirscan-1.0.0-py3-none-macosx_11_0_x86_64.whl

Download URL tapirscan-1.0.0-py3-none-macosx_11_0_x86_64.whl
Size 5.1 MB
Tags Python 3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
ca63ffe96ae582c227ea04f338ed4c6d88995aa962ae0213d9b0e565f96d2cd5
BLAKE2b-256 checksum
How to use checksums
9f9ef83c3817a97faae0bf7d682ebdc43b0ed7229b659730e87da75c8e1f17ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release files / tapirscan-1.0.0-py3-none-macosx_11_0_arm64.whl

Download URL tapirscan-1.0.0-py3-none-macosx_11_0_arm64.whl
Size 4.7 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7c26147dc07241951527c318ce8250516063dd6bca6f59aab4bd718bd8bd42f6
BLAKE2b-256 checksum
How to use checksums
482e33a569fc4d70188b7326480d4e9c68c8a423da8b2f2c2e0c0fb8dd3bd345
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 15, 2026.

Transparency log

Release history Release notifications | RSS feed

1.2.1

5 release files

1.2.0

5 release files

1.1.0

5 release files

This release

1.0.0 This release

5 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page