smiley преди 1 месец
родител
ревизия
c55c64dfa0

+ 0 - 34
README.md

@@ -125,40 +125,6 @@ Also, have a look [in the examples folder](https://github.com/chillerlan/php-qrc
 </p>
 
 
-## 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!

+ 24 - 22
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 |

+ 1 - 1
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.

+ 2 - 0
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

+ 1 - 41
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;
-
-```

+ 3 - 1
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)

Файловите разлики са ограничени, защото са твърде много
+ 72 - 0
docs/Usage/Logos.md


+ 0 - 20
docs/Usage/Quickstart.md

@@ -41,26 +41,6 @@ and [configuration settings](../Usage/Configuration-settings.md) for a list of a
 Also, have a look [in the examples folder](https://github.com/chillerlan/php-qrcode/tree/main/examples) for some more usage examples.
 
 
-## Reading QR Codes
-
-Using the built-in QR Code reader is pretty straight-forward:
-```php
-try{
-	$result = (new QRCode)->readFromFile('path/to/file.png'); // -> DecoderResult
-
-	// you can now use the result instance...
-	$content = $result->data;
-
-	// ...or simply cast the result instance to string to get the content
-	$content = (string)$result;
-}
-catch(Throwable $exception){
-	// handle exception...
-}
-```
-It's generally a good idea to wrap the reading in a try/catch block to handle any errors that may occur in the process.
-
-
 ## Notes
 The QR encoder, especially the subroutines for mask pattern testing, can cause high CPU load on increased matrix size.
 You can avoid a part of this load by choosing a fast output module, like SVG.

+ 101 - 0
docs/Usage/Reading-QRCodes.md

@@ -0,0 +1,101 @@
+# 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.

+ 1 - 1
docs/conf.py

@@ -44,7 +44,7 @@ lexers['php-annotations'] = PhpLexer(startinline=True)
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
 
 project = u'PHP-QRCode'
-copyright = u'2023, smiley'
+copyright = u'2025, smiley'
 author = u'smiley'
 epub_author = u'smiley'
 

+ 2 - 0
docs/index.rst

@@ -21,6 +21,8 @@ This work is licensed under the Creative Commons Attribution 4.0 International (
    Usage/Quickstart.md
    Usage/Advanced-usage.md
    Usage/Configuration-settings.md
+   Usage/Reading-QRCodes.md
+   Usage/Logos.md
 
 .. toctree::
    :maxdepth: 3

Някои файлове не бяха показани, защото твърде много файлове са промени