diff --git a/README.md b/README.md index f3fb749d7..b97c5e300 100644 --- a/README.md +++ b/README.md @@ -125,40 +125,6 @@ Also, have a look [in the examples folder](https://github.com/chillerlan/php-qrc
-## Reading QR Codes - -Using the built-in QR Code reader is pretty straight-forward: - -```php -// it's generally a good idea to wrap the reader in a try/catch block because it WILL throw eventually -try{ - $result = (new QRCode)->readFromFile('path/to/file.png'); // -> DecoderResult - - // you can now use the result instance... - $content = $result->data; - $matrix = $result->getMatrix(); // -> QRMatrix - - // ...or simply cast it to string to get the content: - $content = (string)$result; -} -catch(Throwable $e){ - // oopsies! -} -``` - - -# Shameless advertising - -Hi, please check out some of my other projects that are way cooler than qrcodes! - -- [js-qrcode](https://github.com/chillerlan/js-qrcode) - a javascript port of this library -- [php-authenticator](https://github.com/chillerlan/php-authenticator) - a Google Authenticator implementation (see [authenticator example](https://github.com/chillerlan/php-qrcode/blob/main/examples/authenticator.php)) -- [php-httpinterface](https://github.com/chillerlan/php-httpinterface) - a PSR-7/15/17/18 implemetation -- [php-oauth](https://github.com/chillerlan/php-oauth) - an OAuth 1/2 client library, fully PSR-7/PSR-17/PSR-18 compatible -- [php-database](https://github.com/chillerlan/php-database) - a database client & querybuilder for MySQL, Postgres, SQLite, MSSQL, Firebird -- [php-tootbot](https://github.com/php-tootbot/tootbot-template) - a Mastodon bot library (see [@dwil](https://github.com/php-tootbot/dwil)) - - # Disclaimer! I don't take responsibility for molten CPUs, misled applications, failed log-ins etc.. Use at your own risk! diff --git a/docs/Appendix/Performance-considerations.md b/docs/Appendix/Performance-considerations.md index 56bfb79dc..3fa21e790 100644 --- a/docs/Appendix/Performance-considerations.md +++ b/docs/Appendix/Performance-considerations.md @@ -44,35 +44,37 @@ is a complex and costly operation that is necessary to ensure the symbol is read to override the evaluation and manually set a mask pattern, this is not recommended unless you know exactly what you're doing as it can render a QR symbol unreadable. -The table below shows the performance impact (in miliseconds) of the mask pattern evaluation for each version, the times may vary between systems. +The table below shows the performance impact (in miliseconds) of the mask pattern evaluation for select versions, the times may vary between systems. -| version | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -|-----------|--------:|--------:|--------:|--------:|--------:|--------:|--------:|--------:|--------:|--------:| -| **1-10** | 4.414 | 5.697 | 7.986 | 9.221 | 10.877 | 11.293 | 13.901 | 15.563 | 18.142 | 20.501 | -| **11-20** | 22.662 | 27.779 | 29.622 | 33.017 | 36.358 | 39.712 | 43.685 | 47.121 | 51.389 | 57.865 | -| **21-30** | 59.753 | 68.502 | 68.523 | 72.866 | 78.245 | 83.593 | 88.327 | 94.921 | 103.394 | 106.358 | -| **31-40** | 113.311 | 120.484 | 126.215 | 132.931 | 139.783 | 145.617 | 170.576 | 165.996 | 167.365 | 175.821 | +| version | time (ms) | +|---------|----------:| +| **1** | 2.285 | +| **5** | 5.867 | +| **10** | 12.737 | +| **20** | 34.045 | +| **30** | 64.914 | +| **40** | 107.027 | ## Output Output rendering depends heavily on the size of the QR matrix, the desired type and the underlying libraries and/or PHP extensions. -Especially the rendering of raster images through GD or ImagMagick can be very slow, depending on [the scale setting](../Usage/Configuration-settings.md#scale), +Especially the rendering of raster images through GD or ImageMagick can be very slow, depending on [the scale setting](../Usage/Configuration-settings.md#scale), filters and image type. Below a comparison of the performance for the several built-in output classes (times in miliseconds, scale = 5): -| | v5 | v10 | v15 | v20 | v25 | v30 | v35 | v40 | -|-------------------|-------:|-------:|--------:|--------:|--------:|--------:|--------:|--------:| -| **QRMarkupSVG** | 3.732 | 8.645 | 13.846 | 21.127 | 32.842 | 43.753 | 56.584 | 73.885 | -| **QRMarkupHTML** | 0.522 | 1.308 | 2.062 | 2.761 | 3.907 | 5.201 | 7.931 | 9.572 | -| **QRGdImageBMP** | 5.998 | 12.541 | 20.728 | 32.336 | 46.345 | 62.842 | 81.555 | 106.482 | -| **QRGdImageGIF** | 3.427 | 6.817 | 12.226 | 17.925 | 25.453 | 35.136 | 44.706 | 57.477 | -| **QRGdImageJPEG** | 2.284 | 4.882 | 8.161 | 12.097 | 17.333 | 23.862 | 30.327 | 40.226 | -| **QRGdImagePNG** | 4.523 | 9.377 | 16.581 | 26.207 | 36.516 | 49.066 | 63.765 | 82.074 | -| **QRGdImageWEBP** | 8.211 | 17.367 | 30.079 | 47.095 | 69.668 | 91.378 | 119.869 | 150.288 | -| **QRStringJSON** | 0.043 | 0.066 | 0.107 | 0.158 | 0.215 | 0.301 | 0.369 | 0.492 | -| **QRStringText** | 0.229 | 0.387 | 0.628 | 0.952 | 1.312 | 1.759 | 2.329 | 3.045 | -| **QRImagick** | 37.694 | 68.808 | 114.415 | 172.962 | 242.338 | 325.085 | 419.999 | 529.897 | -| **QRFpdf** | 6.578 | 12.466 | 21.169 | 33.021 | 45.469 | 61.198 | 80.092 | 100.059 | -| **QREps** | 1.269 | 2.694 | 4.515 | 6.933 | 11.049 | 14.181 | 20.799 | 25.886 | +| | v5 | v10 | v20 | v30 | v40 | +|-------------------|-------:|-------:|--------:|--------:|--------:| +| **QRMarkupSVG** | 3.732 | 8.645 | 21.127 | 43.753 | 73.885 | +| **QRMarkupHTML** | 0.522 | 1.308 | 2.761 | 5.201 | 9.572 | +| **QRGdImageBMP** | 5.998 | 12.541 | 32.336 | 62.842 | 106.482 | +| **QRGdImageGIF** | 3.427 | 6.817 | 17.925 | 35.136 | 57.477 | +| **QRGdImageJPEG** | 2.284 | 4.882 | 12.097 | 23.862 | 40.226 | +| **QRGdImagePNG** | 4.523 | 9.377 | 26.207 | 49.066 | 82.074 | +| **QRGdImageWEBP** | 8.211 | 17.367 | 47.095 | 91.378 | 150.288 | +| **QRStringJSON** | 0.043 | 0.066 | 0.158 | 0.301 | 0.492 | +| **QRStringText** | 0.229 | 0.387 | 0.952 | 1.759 | 3.045 | +| **QRImagick** | 37.694 | 68.808 | 172.962 | 325.085 | 529.897 | +| **QRFpdf** | 6.578 | 12.466 | 33.021 | 61.198 | 100.059 | +| **QREps** | 1.269 | 2.694 | 6.933 | 14.181 | 25.886 | diff --git a/docs/Appendix/Terminology.md b/docs/Appendix/Terminology.md index 7ee03b23f..a7e4127e4 100644 --- a/docs/Appendix/Terminology.md +++ b/docs/Appendix/Terminology.md @@ -2,7 +2,7 @@ ## QR Code -A [*QR code*](https://en.wikipedia.org/wiki/QR_code) (quick-response code) is a type of two-dimensional matrix barcode, invented +A [*QR code*](https://en.wikipedia.org/wiki/QR_code) (quick-response code), sometimes referred to as *QR symbol* or simply just *symbol*, is a type of two-dimensional matrix barcode, invented in 1994 by Japanese company [Denso Wave](https://www.qrcode.com/en/faq.html#patentH2Title) for labelling automobile parts. The QR labelling system was applied beyond the automobile industry due to its fast readability and greater storage capacity compared to standard UPC barcodes. diff --git a/docs/Readme.md b/docs/Readme.md index 139831d5f..b0f18ede9 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -62,6 +62,8 @@ The markdown sources for the [Read the Docs online manual](https://php-qrcode.re - [Quickstart](./Usage/Quickstart.md) - [Advanced usage](./Usage/Advanced-usage.md) - [Configuration settings](./Usage/Configuration-settings.md) +- [Reading QR Codes](./Usage/Reading-QRCodes.md) +- [Logos and logo space](./Usage/Logos.md) ### Customizing output diff --git a/docs/Usage/Advanced-usage.md b/docs/Usage/Advanced-usage.md index 07e2f5d21..c3c29eb4f 100644 --- a/docs/Usage/Advanced-usage.md +++ b/docs/Usage/Advanced-usage.md @@ -173,7 +173,7 @@ $output = $qrcode->render(); $qrcode->render(null, '/path/to/qrcode.svg'); ``` -The [`QRDataModeInterface`](https://github.com/chillerlan/php-qrcode/blob/main/src/Data/QRDataModeInterface.php) offers the `validateString()` method (implemended for `AlphaNum`, `Byte`, `Hanzi`, `Kanji` and `Number`). +The [`QRDataModeInterface`](https://github.com/chillerlan/php-qrcode/blob/main/src/Data/QRDataModeInterface.php) offers the `validateString()` method (implemented for `AlphaNum`, `Byte`, `Hanzi`, `Kanji` and `Number`). This method is used internally when a data mode is invoked, but it can come in handy if you need to check input data beforehand. ```php @@ -185,33 +185,6 @@ $qrcode->addHanziSegment($data); ``` -### QR Code reader - -In some cases it might be necessary to increase the contrast of a QR Code image: - -```php -$options->readerUseImagickIfAvailable = true; -$options->readerIncreaseContrast = true; -$options->readerGrayscale = true; - -$qrcode = new QRCode($options); - -$result = $qrcode->readFromFile('path/to/qrcode.png'); -$result = $qrcode->readFromBlob($imagedata); -``` - -The `QRMatrix` object from the [`DecoderResult`](https://github.com/chillerlan/php-qrcode/blob/main/src/Decoder/DecoderResult.php) can be reused: - -```php -$matrix = $result->getQRMatrix(); - -// ...matrix modification... - -$output = (new QRCode($options))->renderMatrix($matrix); - -// ...output -``` - ## Common output options ### Save to file @@ -266,16 +239,3 @@ $imagick = $qrcode->render($data); echo $imagick->getImageBlob(); ``` - - -### Add a logo space - - -```php -$options->addLogoSpace = true; -$options->logoSpaceWidth = 9; -$options->logoSpaceHeight = 9; -$options->logoSpaceStartX = 10; -$options->logoSpaceStartY = 10; - -``` diff --git a/docs/Usage/Configuration-settings.md b/docs/Usage/Configuration-settings.md index 7edfd7043..9b24b0636 100644 --- a/docs/Usage/Configuration-settings.md +++ b/docs/Usage/Configuration-settings.md @@ -191,6 +191,7 @@ Specifies which module types to exclude when `QROptions::$drawCircularModules` i (default: `[]`) + ## connectPaths Whether to connect the paths for the several module types to avoid weird glitches when using gradients etc. @@ -215,6 +216,7 @@ Currentty used in `QREps` and `QRMarkupSVG`. Specify which paths/patterns to exclude from connecting if `QROptions::$connectPaths` is set to `true` + **See also:** - `\chillerlan\QRCode\QROptionsTrait::$connectPaths` @@ -229,6 +231,7 @@ Module values map - `QREps`: `[C, M, Y, K]` // 0-255 + **See also:** - `\chillerlan\QRCode\Output\QROutputAbstract::setModuleValues()` @@ -296,7 +299,6 @@ Defaults to `QROptions::$bgColor`. - `QRImagick`: `"color_str"`, this color is set in `Imagick::transparentPaintImage()` - **See also:** - [php.net: `\imagecolortransparent()`](https://www.php.net/manual/function.imagecolortransparent) diff --git a/docs/Usage/Logos.md b/docs/Usage/Logos.md new file mode 100644 index 000000000..90721d23a --- /dev/null +++ b/docs/Usage/Logos.md @@ -0,0 +1,74 @@ +# Logos and logo space + +## Info + +Brand logos on QR Codes are a common sight and it's quite simple to produce them, however, there are some pitfalls to avoid in order to properly create branded QR Codes. + +**Logos are not part of any specification, instead, placing a logo on a QR symbol is merely abusing the error correction capacity and the symbol may become unreadable, especially in environments with chances to receive damage, such as prints** (bug reports regarding unreadable logo QR Codes will not be accepted, you have been warned). + +As a general rule, the [ECC level](./../Appendix/Terminology.md#ecc-error-correction-coding) should be set to **H** (30%) and a minimum version number of 7 or higher is recommended, even though the data would fit in a much smaller symbol: + +```php +$options = new QROptions; + +$options->version = Version::AUTO; +$options->versionMin = 7; +$options->eccLevel = EccLevel::H; +``` + +For best results, the logo (-space) should not exceed 1/5 of the symbol width and height, excluding the quiet zone. Overwriting the [function patterns](./../Appendix/Terminology.md#function-patterns) should be avoided, +however, overwriting one of the [alignment patterns](./../Appendix/Terminology.md#alignment-pattern) is almost inevitable (but also not much of an issue). + + + +## Adding a logo space + +A logo space might not be necessary if the QR Code is rendered in a raster format via GD or ImageMagick, where a logo and a possibly required space can be added with the respective built-in functions. +For vector/markup based formats it can be useful to prevent the rendering of modules in the area where the logo is supposed to be. + +The `QRMatrix` instance offers a method to clear a rectangular space, that can be utilized from the options: + +```php +$options->addLogoSpace = true; + +// either width or height must be given, if only one dimension is given, the space is assumed square +$options->logoSpaceWidth = 9; +$options->logoSpaceHeight = 9; + +// the top left corner of the space, both values are optional +$options->logoSpaceStartX = 10; +$options->logoSpaceStartY = 10; +``` + +It's also possible to call `QRMatrix::setLogoSpace()` from within a custom output class, e.g. to [dynamically scale the logo space](https://github.com/chillerlan/php-qrcode/blob/d54ebd8b18520525c4fd4e05fffc1768aefed187/examples/svgWithLogo.php#L31-L34): + +```php +$size = (int)ceil($this->moduleCount * $logoScale); + +$this->matrix->setLogoSpace($size, $size); +``` + +Further, the `QRMatrix` instance can be modified from outside too: + +```php +$qrcode = new QRCode($options); + +// create a matrix instance +$matrix = $qrcode + ->addByteSegment('https://www.youtube.com/watch?v=dQw4w9WgXcQ') + ->getQRMatrix(); + +// modify +for($y = $startY; $y < $endY; $y++){ + for($x = $startX; $x < $endX; $x++){ + $matrix->set($x, $y, false, QRMatrix::M_LOGO); + } +} + +// render the QR Code +$out = $qrcode->renderMatrix($matrix); +``` + +
+
+