Reading-QRCodes.md.txt 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # Reading QR Codes
  2. ## Basic usage
  3. The QR Code reader can be called either from a `QRCode` instance or invoked directly via the `Decoder` class with a `QROptions` (`QRCodeReaderOptionsTrait`) instance.
  4. ```php
  5. $options = new QROptions
  6. $options->readerUseImagickIfAvailable = true;
  7. $options->readerIncreaseContrast = true;
  8. $options->readerGrayscale = true;
  9. $options->readerInvertColors = false;
  10. ```
  11. The option `QROptions::$readerUseImagickIfAvailable` is exclusive to the `QRCode` instance in order to decide which `LuminanceSourceInterface` to use.
  12. The `QRCode` instance has 3 convenience methods related to the reader:
  13. ```php
  14. $qrcode = new QRCode($options)
  15. $result = $qrcode->readFromFile('path/to/qrcode.png');
  16. $result = $qrcode->readFromBlob($imagedata);
  17. // from a luminance source instance
  18. $source = IMagickLuminanceSource::fromBlob($imagedata, $options);
  19. $result = $qrcode->readFromSource($source);
  20. ```
  21. ## The `LuminanceSourceInterface`
  22. 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.
  23. 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:
  24. from an `Imagick` instance:
  25. ```php
  26. $imagick = new Imagick;
  27. $imagick->readImageBlob($imagedata);
  28. $source = new IMagickLuminanceSource($imagick, $options);
  29. ```
  30. from a `GdImage` instance:
  31. ```php
  32. $gdimage = imagecreatefromstring($imagedata);
  33. $source = new GDLuminanceSource($gdimage, $options);
  34. ```
  35. ## The `Decoder`
  36. The `Decoder` takes a `QROptions` instance as parameter, which currently has no use - it is only handed over for possible future uses.
  37. ```php
  38. $result = (new Decoder($options))->decode($source);
  39. ```
  40. That is all! The decoder will either return a `DecoderResult` instance or throw an exception.
  41. It is generally a good practice to wrap the reading in a try/catch block:
  42. ```php
  43. try{
  44. $result = $qrcode->readFromFile('path/to/file.png'); // -> DecoderResult
  45. // ... do stuff with the result
  46. }
  47. catch(QRCodeDecoderException){
  48. // ... adjust input image (position, contrast, invert, sharpen) and repeat the process
  49. }
  50. ```
  51. You can now use the result instance:
  52. ```php
  53. $content = $result->data;
  54. // ...or simply cast it to string:
  55. $content = (string)$result;
  56. ```
  57. The result instance also holds `Version`, `EccLevel`, `MaskPattern` and `BitBuffer` instances, as well as an array of `FinderPattern` instances,
  58. it also offers a method that returns a `QRMatrix` instance populated with the detected settings:
  59. ```php
  60. $matrix = $result->getQRMatrix();
  61. // ...matrix modification...
  62. $output = (new QRCode($options))->renderMatrix($matrix);
  63. // ...dump output
  64. ```
  65. ## General considerations
  66. 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.
  67. 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.
  68. 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.
  69. The test data set seemed to randomly produce errors depending on the given module scale, independent of the luminance source.
  70. However, scaling down to get a smaller module size isn't the best solution as it may produce additional challenges due to filter artifacts.