NAME

Imager::zxing - decode barcodes from Imager images using libzxing

SYNOPSIS

use Imager::zxing;
my $decoder = Imager::zxing::Decoder->new;
# list accepted formats separated by '|'
print $decoder->formats;
# list available formats
print $decoder->availFormats
# set the accepted formats
$decoder->setFormats("DataMatrix|QRCode")
  or die $decoder->error;

# decode any barcodes
my $im = Imager->new(file => "somefile.png");
my @results = $decoder->decode($im);

for my $result (@results) {
  print $result->text, "\n";
}

my $encoder = Imager::zxing::Encoder->new("QRCode");
my $im = $encoder->encode($text, $width, $height);

DESCRIPTION

A primitive wrapper around zxing-cpp

This requires at least 1.4.0 of zxing-cpp, but 2.1.0 is preferable.

Decoding

To use this:

  1. Create a decoder object:

    use Imager::zxing;
    my $decoder = Imager::zxing::Decoder->new;
  2. Configure it if needed, most likely by setting the accepted barcode encodings:

    $decoder->set_formats("DataMatrix|QRCode");
  3. Load an image using Imager:

    my $img = Imager->new(file => "somename.png")
      or die "Cannot load image ", Imager->errstr;

    The available file formats depends on the libraries Imager was built with.

  4. Decode the barcode:

    my @results = $decoder->decode($img)
      or die "No barcodes found";
  5. Process the results:

    for my $r (@results) {
      print $r->format, ": ", $r->text, "\n";
    }

Encoding

To use this:

  1. Create an encoder object, this requires the barcode type:

    use Imager::zxing;
    my $encoder = Imager::zxing::Encoder->new("QRCode");
  2. Configure it if needed, the defaults will work in most cases.

  3. Encode to an Imager image:

    my $image = $encoder->encode($text, $width, $height)
      or die Imager->errstr;
  4. Save or present the image:

    # save to a file
    $image->write(file => $filename)
      or die $image->errstr;

Imager::zxing::Decoder class methods

  • new

    my $decoder = Imager::zxing::Decoder->new;

    Create a new decoder object, does not accept any parameters.

    Default is to process all available barcode formats.

  • availFormats

    my @formats = Imager::zxing::Decoder->availFormats

    Returns a list of the barcode formats that are decodable.

Decoder object methods

Create a decoder with:

my $decoder = Imager::zxing::Decoder->new;

Decoding

  • decode(image)

    Attempts to decode barcodes from the supplied Imager image object.

    Returns a list of result objects, or an empty list if none are found.

    my $img = Imager->new(file => "somefile.png") or die Imager->errstr;
    my @results = $decoder->decode($img);

Settings

  • formats()

    Returns the formats the decoder accepts as a | separated string.

    print $decoder->formats
    # default output:
    # Aztec|Codabar|Code39|Code93|Code128|DataBar|DataBarExpanded|DataMatrix|EAN-8|EAN-13|ITF|MaxiCode|PDF417|QRCode|UPC-A|UPC-E|MicroQRCode
  • setFormats(formats)

    Sets the barcode formats that the decoder will decode, as a space, | or comma separated string.

    $decoder->setFormats("DataMatrix|QRCode");

There are various boolean options that can be set with setoption(val) setting the option and option() returning the current value.

  • tryHarder

    Spend more time to try to find a barcode; optimize for accuracy, not speed.

    $decoder->setTryHarder(0); # a bit faster
    my $val = $decoder->tryHarder;

    Default: true.

  • tryDownscale

    Also try detecting code in downscaled images (depending on image size).

    $decoder->setTryDownscale(0); # a bit faster
    my $val = $decoder->tryDownscale;

    Default: true.

  • isPure)

    Set to non-zero to only accept results where the image is an aligned image where the image is only the barcode.

    $decoder->setIsPure(1);
    my $val = $decoder->isPure();

    Default: false.

    Note: this appears to be non-functional in my testing, this accepted a rotated image.

    This could previously be set with set_pure(), which has been renamed to better match the C++ API.

  • tryCode39ExtendedMode

    If true, the Code-39 reader will try to read extended mode.

    $decoder->setTryCode39ExtendedMode(0);
    my $val = $decoder->tryCode39ExtendedMode();

    Default: false.

  • validateCode39CheckSum

    Assume Code-39 codes employ a check digit and validate it.

    $decoder->validateCode39CheckSum(1);
    my $val = $decoder->validateCode39CheckSum;

    Default: false.

  • validateITFCheckSum

    $decoder->setValidateITFCheckSum(1);
    my $val = $decoder->validateITFCheckSum();

    Assume ITF codes employ a GS1 check digit and validate it.

    Default: false.

  • returnCodabarStartEnd

    If true, return the start and end chars in a Codabar barcode instead of stripping them.

    $decoder->setReturnCodabarStartEnd(1);
    my $val = $decoder->returnCodabarStartEnd();

    Default: false.

  • returnErrors

    Set to non-zero to include results with soft errors such as checksum errors.

    Default: false.

    $decoder->setReturnErrors(1);
    my $val = $decoder->returnErrors();

    This could previously be set with set_return_errors() which is now deprecated to better match the C++ API.

  • tryRotate

    Also try detecting code in 90, 180 and 270 degree rotated images.

    $decoder->setTryRotate(1);
    my $val = $decoder->tryRotate();

    Default: true.

  • tryInvert

    Also try detecting inverted ("reversed reflectance") codes if the format allows for those.

    $decoder->setTryInvert(1);
    my $val = $decoder->tryInvert();

    Default: true. Requires zxing-cpp 2.0.0 or later.

Result object methods

Result objects are returned by the decoder decode() method:

my @results = $decoder->decode($image);
  • text()

    Returns the decoded text.

    my $text = $result->text;
  • isValid()

    True if the result represents a valid decoded barcode.

    Replaces the deprecated is_valid() method.

  • isMirrored()

    True if the result is from a mirrored barcode.

    Replaces the deprecated is_mirrored() method.

  • isInverted()

    True if the barcode image has inverted dark/light. Requires zxing 2.0.0 to be valid.

    Replaces the deprecated is_inverted() method. =item * format()

    The format of the decoded barcode.

  • position()

    The co-ordinates of the top left, top right, bottom left and bottom right points of the decoded barcode in the supplied image, as a list.

  • orientation()

    The rotation of the barcode image in degrees.

Imager::zxing::Encoder class methods

new($type)

Create a new encoder for barcode format $type.

Note that zxing doesn't validate the barcode type at this point.

my $encoder = Imager::zxing::Encoder->new("QRCode");
availFormats()

Returns a list of formats that can be encoded.

Note that zxing itself doesn't report this information except by failing to encode. For now this uses a static list based on inspection of the source.

my @formats = Imager::zxing::Encoder->availFormats();

Imager::zxing::Encoder object methods

encode($text, $width, $height)

Encode the given text as a barcode and return the result as an Imager image object.

The permitted content for $text depends on the barcode type.

Any error will be returned via Imager->errstr.

my $image = $encoder->encode("https://www.perl.org", 100, 100);
setEccLevel($level)

Set the error correction level for the barcode, this depends on the barcode type being encoded.

$encoder->setEccLevel(2);
setIsBytes($bool)

Set how the text passed to encode() is treated, typically it is treated as text and passed to zxing as UTF-8.

This can be used to pass the string as bytes. If this is true the $text parameter passed to encode() may contain only codepoints in the range 0 to 0xFF.

$encoder->setIsBytes(1);  # or builtin::true in a newer perl
setHasQuietZone($bool)

If true a small blank margin is added to the generated image.

$encoder->setHasQuietZone(1);

This may change depending on how the zxing API evolves.

setFormat($imager_format)

One of RGB, RGBA, Gray or Palette to control whether an RGB, RGB with alpha, grayscale or indexed is returned by encode().

This defaults to RGB.

$encoder->setFormat("Palette");
setForeground($color)
setBackground($color)

Set the foreground and background colors used in the resulting image. Defaults to black and white respectively.

Either accepts an Imager::Color object, or any of the formats Imager normally allows for color parameters:

$encoder->setForeground(Imager::Color->new(0, 32, 32, 255));
$encoder->setBackground("#FFC0C0");

DEPRECATIONS

The following method names from Imager::zxing::Decoder are deprecated, and listed here with their replacements:

set_pure()

Replaced by setIsPure().

set_return_errors()

Replaced by setReturnErrors().

set_formats()

Replaced by setFormats()

avail_formats() class method

Replaced by availFormats()

The following method names from Imager::zxing::Decoder::Result are deprecated and listed here with their replacements:

content_type()

Replaced by contentType()

is_mirrored()

Replaced by isMirrored()

is_valid()

Replaced by isValid()

is_inverted()

Replaced by isInverted().

These have been renamed to better match the C++ API. The old names are available without warning for now, but will produce a default-on warning in a future release and removed at some point after that.

Support for zxing 1.4.0 is deprecated and will likely be removed soon.

BUGS

If you build zxing-cpp with its experimental API enabled Imager::zxing will crash. Unfortunately the define used to detect this isn't propagated into Version.h nor into the pkg-config file, so I don't have a simple way to detect this. https://github.com/zxing-cpp/zxing-cpp/issues/964

You will see some deprecated method warnings when building Imager::zxing. For now I continue to expose these methods, so I need to call them. Once zxing-cpp removes them I'll stop calling them, at least for the versions of zxing-cpp involved.

When building with an older perl you may see a build warning for use of volatile in the declaration of call_sv(), this is a perl bug which has been fixed in perl. https://github.com/Perl/perl5/pull/21581

LICENSE

Imager::zxing is licensed under the same terms as perl itself.

SEE ALSO

Imager

AUTHOR

Tony Cook <tony@develop-help.com>