mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-08-23 22:28:03 +00:00
102 lines
3.8 KiB
Markdown
102 lines
3.8 KiB
Markdown
# Reading QR Codes
|
|
|
|
## Basic usage
|
|
|
|
The QR Code reader can be called either from a `QRCode` instance or invoked directly via the `Decoder` class with a `QROptions` (`QRCodeReaderOptionsTrait`) instance.
|
|
|
|
```php
|
|
$options = new QROptions
|
|
|
|
$options->readerUseImagickIfAvailable = true;
|
|
$options->readerIncreaseContrast = true;
|
|
$options->readerGrayscale = true;
|
|
$options->readerInvertColors = false;
|
|
```
|
|
|
|
The option `QROptions::$readerUseImagickIfAvailable` is exclusive to the `QRCode` instance in order to decide which `LuminanceSourceInterface` to use.
|
|
The `QRCode` instance has 3 convenience methods related to the reader:
|
|
```php
|
|
$qrcode = new QRCode($options)
|
|
|
|
$result = $qrcode->readFromFile('path/to/qrcode.png');
|
|
$result = $qrcode->readFromBlob($imagedata);
|
|
|
|
// from a luminance source instance
|
|
$source = IMagickLuminanceSource::fromBlob($imagedata, $options);
|
|
$result = $qrcode->readFromSource($source);
|
|
```
|
|
|
|
## The `LuminanceSourceInterface`
|
|
|
|
The method `QRCode::readFromSource()` takes a `LuminanceSourceInterface` instance as parameter and is mainly for internal use, as you can invoke and call the decoder directly with it.
|
|
Each `LuminanceSourceInterface` has the static convenience methods `fromFile()` and `fromBlob()` that will invoke the instance with the respective parameters, alternatively the instance(s) can be invoked manually:
|
|
|
|
from an `Imagick` instance:
|
|
```php
|
|
$imagick = new Imagick;
|
|
$imagick->readImageBlob($imagedata);
|
|
|
|
$source = new IMagickLuminanceSource($imagick, $options);
|
|
```
|
|
|
|
from a `GdImage` instance:
|
|
|
|
```php
|
|
$gdimage = imagecreatefromstring($imagedata);
|
|
|
|
$source = new GDLuminanceSource($gdimage, $options);
|
|
```
|
|
|
|
## The `Decoder`
|
|
|
|
The `Decoder` takes a `QROptions` instance as parameter, which currently has no use - it is only handed over for possible future uses.
|
|
|
|
```php
|
|
$result = new Decoder($options)->decode($source);
|
|
```
|
|
|
|
That is all! The decoder will either return a `DecoderResult` instance or throw an exception.
|
|
It is generally a good practice to wrap the reading in a try/catch block:
|
|
|
|
```php
|
|
try{
|
|
$result = $qrcode->readFromFile('path/to/file.png'); // -> DecoderResult
|
|
|
|
// ... do stuff with the result
|
|
}
|
|
catch(QRCodeDecoderException){
|
|
// ... adjust input image (position, contrast, invert, sharpen) and repeat the process
|
|
}
|
|
```
|
|
|
|
You can now use the result instance:
|
|
|
|
```php
|
|
$content = $result->data;
|
|
// ...or simply cast it to string:
|
|
$content = (string)$result;
|
|
```
|
|
|
|
The result instance also holds `Version`, `EccLevel`, `MaskPattern` and `BitBuffer` instances, as well as an array of `FinderPattern` instances,
|
|
it also offers a method that returns a `QRMatrix` instance populated with the detected settings:
|
|
|
|
```php
|
|
$matrix = $result->getQRMatrix();
|
|
|
|
// ...matrix modification...
|
|
|
|
$output = new QRCode($options)->renderMatrix($matrix);
|
|
|
|
// ...dump output
|
|
```
|
|
|
|
|
|
## General considerations
|
|
|
|
The QR Code reader reads the given QR symbol in a single pass, unlike e.g. a reader app on a mobile device with a camera, which repeats the reading process for a sequence of frames from the video input and takes the "best" result.
|
|
It means that this reader may fail to properly decode a symbol that reads perfectly fine on a mobile - you'd need to emulate the same process of sequential reading while adjusting the input image to get a similar result.
|
|
|
|
Further it seems ([per observation](https://github.com/chillerlan/php-qrcode/blob/92346420a5a88aeeb8dc16f731ef1f93331635d3/tests/QRCodeReaderTestAbstract.php#L168-L172)) that the reader favors smaller module sizes (1-2 pixel side length) from version 20 onwards.
|
|
The test data set seemed to randomly produce errors depending on the given module scale, independent of the luminance source.
|
|
However, scaling down to get a smaller module size isn't the best solution as it may produce additional challenges due to filter artifacts.
|