From 3783ef7b0f4935dcadb9bc123dbb85126ff31d6a Mon Sep 17 00:00:00 2001 From: smiley Date: Thu, 13 Jul 2023 18:33:06 +0200 Subject: [PATCH] :sparkles: RTFD! --- docs/API-DecoderResult.md | 24 +++ docs/API-QRCode.md | 65 ++++++++ docs/API-QRMatrix.md | 75 +++++++++ docs/API-QROptions.md | 78 +++++++++ docs/API-QROutputInterface.md | 29 ++++ docs/Appendix-Glossary.md | 306 ++++++++++++++++++++++++++++++++++ docs/Readme.md | 4 +- docs/Usage-Overview.md | 81 +++++---- docs/index.rst | 11 ++ 9 files changed, 641 insertions(+), 32 deletions(-) create mode 100644 docs/API-DecoderResult.md create mode 100644 docs/API-QRCode.md create mode 100644 docs/API-QRMatrix.md create mode 100644 docs/API-QROptions.md create mode 100644 docs/API-QROutputInterface.md create mode 100644 docs/Appendix-Glossary.md diff --git a/docs/API-DecoderResult.md b/docs/API-DecoderResult.md new file mode 100644 index 000000000..324c45145 --- /dev/null +++ b/docs/API-DecoderResult.md @@ -0,0 +1,24 @@ +# `DecoderResult` + +The full phpDocumentor API documentation can be found at [chillerlan.github.io/php-qrcode](https://chillerlan.github.io/php-qrcode/classes/chillerlan-QRCode-Decoder-DecoderResult.html). + +## Methods + +| method | return | description | +|--------------------------------------------|------------|------------------------------------------------------------------------------------------------------------| +| `__construct(iterable $properties = null)` | - | used internally by [`Decoder`](https://github.com/chillerlan/php-qrcode/blob/main/src/Decoder/Decoder.php) | +| `__toString()` | `string` | returns the data contained in the QR symbol | +| `hasStructuredAppend()` | `bool` | | +| `getQRMatrix()` | `QRMatrix` | | + +## Magic Properties (read-only) + +| property | type | description | +|-----------------------------|---------------|------------------| +| `$rawBytes` | `BitBuffer` | | +| `$version` | `Version` | | +| `$eccLevel` | `EccLevel` | | +| `$maskPattern` | `MaskPattern` | | +| `$data` | `string` | defaults to `''` | +| `$structuredAppendParity` | `int` | defaults to `-1` | +| `$structuredAppendSequence` | `int` | defaults to `-1` | diff --git a/docs/API-QRCode.md b/docs/API-QRCode.md new file mode 100644 index 000000000..fa7cf279d --- /dev/null +++ b/docs/API-QRCode.md @@ -0,0 +1,65 @@ +# `QRCode` + +The full phpDocumentor API documentation can be found at [chillerlan.github.io/php-qrcode](https://chillerlan.github.io/php-qrcode/classes/chillerlan-QRCode-QRCode.html). + + +## Methods + +| method | return | description | +|-----------------------------------------------------------|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `__construct(SettingsContainerInterface $options = null)` | - | see [`QROptions`](./API-QROptions.md) and [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerInterface.php) | +| `setOptions(SettingsContainerInterface $options)` | `self` | Sets an options instance, internally called via the constructor | +| `render(string $data, string $file = null)` | `mixed` | renders a QR Code for the given `$data` and `QROptions`, saves `$file` optionally, output depends on the chosen mode, see `QROutputInterface::dump()` | +| `renderMatrix(QRMatrix $matrix, string $file = null)` | `mixed` | renders a QR Code for the given `QRMatrix` and `QROptions`, saves `$file` optionally, output depends on the chosen mode, see `QROutputInterface::dump()` | +| `getQRMatrix()` | `QRMatrix` | returns a `QRMatrix` object for the given `$data` and current `QROptions` | +| `addSegment(QRDataModeInterface $segment)` | `self` | Adds a `QRDataModeInterface` segment | +| `clearSegments()` | `self` | Clears the data segments array | +| `addNumericSegment(string $data)` | `self` | Adds a numeric data segment | +| `addAlphaNumSegment(string $data)` | `self` | Adds an alphanumeric data segment | +| `addKanjiSegment(string $data)` | `self` | Adds a Kanji data segment (Japanese 13-bit double-byte characters, Shift-JIS) | +| `addHanziSegment(string $data)` | `self` | Adds a Hanzi data segment (simplified Chinese 13-bit double-byte characters, GB2312/GB18030) | +| `addByteSegment(string $data)` | `self` | Adds an 8-bit byte data segment | +| `addEciDesignator(int $encoding)` | `self` | Adds a standalone ECI designator | +| `addEciSegment(int $encoding, string $data)` | `self` | Adds an ECI data segment (including designator) | +| `readFromFile(string $path)` | `DecoderResult` | Reads a QR Code from a given file | +| `readFromBlob(string $blob)` | `DecoderResult` | Reads a QR Code from the given data blob | +| `readFromSource(LuminanceSourceInterface $source)` | `DecoderResult` | Reads a QR Code from the given luminance source | + + +### Deprecated methods + +| method | since | replacement | +|------------------------------|---------|--------------------------------------------| +| `getMatrix()` | `5.0.0` | `QRCode::getQRMatrix()` | +| `isNumber(string $string)` | `5.0.0` | `Number::validateString(string $string)` | +| `isAlphaNum(string $string)` | `5.0.0` | `AlphaNum::validateString(string $string)` | +| `isKanji(string $string)` | `5.0.0` | `Kanji::validateString(string $string)` | +| `isByte(string $string)` | `5.0.0` | `Byte::validateString(string $string)` | + + +## Constants + +### Deprecated constants + +| name | since | replacement | +|----------------------|---------|----------------------------------| +| `VERSION_AUTO` | `5.0.0` | `Version::AUTO` | +| `MASK_PATTERN_AUTO` | `5.0.0` | `MaskPattern::AUTO` | +| `OUTPUT_MARKUP_SVG` | `5.0.0` | `QROutputInterface::MARKUP_SVG` | +| `OUTPUT_MARKUP_HTML` | `5.0.0` | `QROutputInterface::MARKUP_HTML` | +| `OUTPUT_IMAGE_PNG` | `5.0.0` | `QROutputInterface::GDIMAGE_PNG` | +| `OUTPUT_IMAGE_JPG` | `5.0.0` | `QROutputInterface::GDIMAGE_JPG` | +| `OUTPUT_IMAGE_GIF` | `5.0.0` | `QROutputInterface::GDIMAGE_GIF` | +| `OUTPUT_STRING_JSON` | `5.0.0` | `QROutputInterface::STRING_JSON` | +| `OUTPUT_STRING_TEXT` | `5.0.0` | `QROutputInterface::STRING_TEXT` | +| `OUTPUT_IMAGICK` | `5.0.0` | `QROutputInterface::IMAGICK` | +| `OUTPUT_FPDF` | `5.0.0` | `QROutputInterface::FPDF` | +| `OUTPUT_CUSTOM` | `5.0.0` | `QROutputInterface::CUSTOM` | +| `ECC_L` | `5.0.0` | `EccLevel::L` | +| `ECC_M` | `5.0.0` | `EccLevel::M` | +| `ECC_Q` | `5.0.0` | `EccLevel::Q` | +| `ECC_H` | `5.0.0` | `EccLevel::H` | +| `DATA_NUMBER` | `5.0.0` | `Mode::NUMBER` | +| `DATA_ALPHANUM` | `5.0.0` | `Mode::ALPHANUM` | +| `DATA_BYTE` | `5.0.0` | `Mode::BYTE` | +| `DATA_KANJI` | `5.0.0` | `Mode::KANJI` | diff --git a/docs/API-QRMatrix.md b/docs/API-QRMatrix.md new file mode 100644 index 000000000..27648e58e --- /dev/null +++ b/docs/API-QRMatrix.md @@ -0,0 +1,75 @@ +# `QRMatrix` + +The full phpDocumentor API documentation can be found at [chillerlan.github.io/php-qrcode](https://chillerlan.github.io/php-qrcode/classes/chillerlan-QRCode-Data-QRMatrix.html). + +## Methods + +| method | return | description | +|----------------------------------------------------------------------------------------|---------------------|----------------------------------------------------------------------------------------------------------------------------| +| `__construct(Version $version, EccLevel $eccLevel)` | - | | +| `initFunctionalPatterns()` | `self` | shortcut to initialize the functional patterns | +| `getMatrix()` | `array` | the internal matrix representation as a 2 dimensional array | +| `getVersion()` | `Version\|null` | the current QR Code version instance | +| `getEccLevel()` | `EccLevel\|null` | the current ECC level instance | +| `getMaskPattern()` | `MaskPattern\|null` | the used mask pattern instance | +| `getSize()` | `int` | the absoulute size of the matrix, including quiet zone (if set). `$version * 4 + 17 + 2 * $quietzone` | +| `get(int $x, int $y)` | `int` | returns the value of the module | +| `set(int $x, int $y, bool $value, int $M_TYPE)` | `self` | sets the `$M_TYPE` value for the module | +| `setArea(int $startX, int $startY, int $width, int $height, bool $value, int $M_TYPE)` | `self` | Fills an area of $width * $height, from the given starting point $startX, $startY (top left) with $value for $M_TYPE | +| `checkType(int $x, int $y, int $M_TYPE)` | `bool` | Checks whether a module is of the given $M_TYPE | +| `checkTypeIn(int $x, int $y, array $M_TYPES)` | `bool` | Checks whether the module at ($x, $y) is in the given array of $M_TYPES, returns true if a match is found, otherwise false | +| `check(int $x, int $y)` | `bool` | checks whether a module is true (dark) or false (light) | +| `checkNeighbours(int $x, int $y, int $M_TYPE = null)` | `int` | Checks the status neighbouring modules of the given module at ($x, $y) and returns a bitmask with the results. | +| `setDarkModule()` | `self` | | +| `setFinderPattern()` | `self` | | +| `setSeparators()` | `self` | | +| `setAlignmentPattern()` | `self` | | +| `setTimingPattern()` | `self` | | +| `setVersionNumber()` | `self` | | +| `setFormatInfo(MaskPattern $maskPattern = null)` | `self` | | +| `setQuietZone(int $quietZoneSize)` | `self` | Draws the "quiet zone" of $quietZoneSize around the matrix | +| `rotate90()` | `self` | Rotates the matrix by 90 degrees clock wise | +| `setLogoSpace(int $width, int $height = null, int $startX = null, int $startY = null)` | `self` | Clears a space of $width * $height in order to add a logo or text. | +| `writeCodewords(BitBuffer $bitBuffer)` | `self` | Maps the interleaved binary data on the matrix | +| `mask(MaskPattern $maskPattern)` | `self` | Applies/reverses the mask pattern | + +### Deprecated methods + +| method | since | replacement | +|-----------------|---------|------------------------------| +| `matrix()` | `5.0.0` | `QRMatrix::getMatrix()` | +| `eccLevel()` | `5.0.0` | `QRMatrix::getEccLevel()` | +| `version()` | `5.0.0` | `QRMatrix::getVersion()` | +| `maskPattern()` | `5.0.0` | `QRMatrix::getMaskPattern()` | +| `size()` | `5.0.0` | `QRMatrix::getSize()` | + +## Constants + +The `_DARK` prefixed constans exist purely for convenience - their value is the same as `QRMatrix::M_XXX\|QRMatrix::IS_DARK`, see [`QROutputInterface`](./API-QROutputInterface.md). + +| name | description | +|--------------------|-----------------------------------------------------------------------------------| +| `IS_DARK` | sets the "dark" flag for the given value: `QRMatrix::M_DATA \| QRMatrix::IS_DARK` | +| `M_NULL` | module not set | +| `M_DARKMODULE` | once per matrix at `$xy = [8, 4 * $version + 9]` | +| `M_DATA` | the actual encoded data | +| `M_DATA_DARK` | convenience | +| `M_FINDER` | the 7x7 finder patterns | +| `M_FINDER_DARK` | convenience | +| `M_FINDER_DOT` | the inner 3x3 block of the finder pattern | +| `M_SEPARATOR` | separator lines along the finder patterns | +| `M_SEPARATOR_DARK` | convenience | +| `M_ALIGNMENT` | the 5x5 alignment patterns | +| `M_ALIGNMENT_DARK` | convenience | +| `M_TIMING` | the timing pattern lines | +| `M_TIMING_DARK` | convenience | +| `M_FORMAT` | format information pattern | +| `M_FORMAT_DARK` | convenience | +| `M_VERSION` | version information pattern | +| `M_VERSION_DARK` | convenience | +| `M_QUIETZONE` | margin around the QR Code | +| `M_QUIETZONE_DARK` | convenience | +| `M_LOGO` | space for a logo image (not used yet) | +| `M_LOGO_DARK` | convenience | +| `M_TEST` | test value | +| `M_TEST_DARK` | convenience | diff --git a/docs/API-QROptions.md b/docs/API-QROptions.md new file mode 100644 index 000000000..9308d73b4 --- /dev/null +++ b/docs/API-QROptions.md @@ -0,0 +1,78 @@ +# `QROptions` +(via `QROptionsTrait`) + +The full phpDocumentor API documentation can be found at [chillerlan.github.io/php-qrcode](https://chillerlan.github.io/php-qrcode/classes/chillerlan-QRCode-QROptions.html). + + +## Methods + +Inherited from [`SettingsContainerAbstract`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerAbstract.php) + +| method | return | info | +|--------------------------------------------|------------------------------|-----------------------------------------------------------------------------------------------------------------| +| `__construct(iterable $properties = null)` | - | calls `construct()` internally after the properties have been set | +| (protected) `construct()` | `void` | calls a method with trait name as replacement constructor for each used trait (similar to PHP4 constructors) | +| `__get(string $property)` | `mixed` | calls `$this->{'get_'.$property}()` if such a method exists | +| `__set(string $property, $value)` | `void` | calls `$this->{'set_'.$property}($value)` if such a method exists | +| `__isset(string $property)` | `bool` | | +| `__unset(string $property)` | `void` | | +| `__toString()` | `string` | a JSON string | +| `toArray()` | `array` | | +| `fromIterable(iterable $properties)` | `SettingsContainerInterface` | | +| `toJSON(int $jsonOptions = null)` | `string` | accepts [JSON options constants](http://php.net/manual/json.constants.php) | +| `fromJSON(string $json)` | `SettingsContainerInterface` | | +| `jsonSerialize()` | `mixed` | implements the [`JsonSerializable`](https://www.php.net/manual/en/jsonserializable.jsonserialize.php) interface | + + +## Properties + +| property | type | default | allowed | description | +|--------------------------------|----------------|---------------------------------|-----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `$version` | `int` | `Version::AUTO` | `1...40`, `Version::AUTO` | [QR Code version number](http://www.qrcode.com/en/about/version.html) | +| `$versionMin` | `int` | `1` | `1...40` | Minimum QR version (if `$version = QRCode::VERSION_AUTO`) | +| `$versionMax` | `int` | `40` | `1...40` | Maximum QR version (if `$version = QRCode::VERSION_AUTO`) | +| `$eccLevel` | `int` | `EccLevel::L` | `EccLevel::X` | Error correct level, where X = L (7%), M (15%), Q (25%), H (30%) | +| `$maskPattern` | `int` | `MaskPattern::AUTO` | `0...7`, `MaskPattern::AUTO` | Mask Pattern to use | +| `$addQuietzone` | `bool` | `true` | * | Add a "quiet zone" (margin) according to the QR code spec | +| `$quietzoneSize` | `int` | `4` | clamped to `0...($matrixSize / 2)` | Size of the quiet zone | +| `$outputType` | `string` | `QROutputInterface::MARKUP_SVG` | `QROutputInterface::XXX` | The built-in output type, XXX can be one of: `MARKUP_HTML`, `MARKUP_SVG`, `GDIMAGE_PNG`, `GDIMAGE_JPG`, `GDIMAGE_GIF`, `STRING_TEXT`, `STRING_JSON`, `IMAGICK`, `EPS`, `FPDF`, `CUSTOM` | +| `$outputInterface` | `string\|null` | `null` | * | The FQCN of the custom `QROutputInterface` if `QROptions::$outputType` is set to `QROutputInterface::CUSTOM` | +| `$returnResource` | `bool` | `false` | * | Return the image resource instead of a render if applicable. | +| `$cachefile` | `string\|null` | `null` | * | Optional cache file path | +| `$imageBase64` | `bool` | `true` | * | Toggle base64 or raw image data (if applicable) | +| `$eol` | `string` | `PHP_EOL` | * | Newline string (HTML, SVG, TEXT) | +| `$bgColor` | `mixed` | `null` | a valid FPDF, GD or Imagick color value | Sets the image background color (if applicable). QRImagick: defaults to "white", QRGdImage: defaults to [255, 255, 255], QRFpdf: defaults to blank internally (white page) | +| `$drawLightModules` | `bool` | `true` | * | Whether to draw the light (false) modules | +| `$drawCircularModules` | `bool` | `false` | * | Specify whether to draw the modules as filled circles | +| `$circleRadius` | `float` | `0.45` | `0.1...0.75` | Specifies the radius of the modules when $svgDrawCircularModules is set to true | +| `$keepAsSquare` | `array` | `[]` | `int[]` | Specifies which module types to exclude when $svgDrawCircularModules is set to true | +| `$connectPaths` | `bool` | `false` | * | Whether to connect the paths for the several module types to avoid weird glitches when using gradients etc. | +| `$excludeFromConnect` | `array` | `[]` | `int[]` | Specify which paths/patterns to exclude from connecting if $svgConnectPaths is set to true | +| `$moduleValues` | `array\|null` | `null` | * | Module values map, see [[Custom module values]] | +| `$addLogoSpace` | `bool` | `false` | * | Toggles logo space creation | +| `$logoSpaceWidth` | `int\|null` | `null` | * | Width of the logo space | +| `$logoSpaceHeight` | `int\|null` | `null` | * | Height of the logo space | +| `$logoSpaceStartX` | `int\|null` | `null` | * | Optional horizontal start position of the logo space (top left corner) | +| `$logoSpaceStartY` | `int\|null` | `null` | * | Optional vertical start position of the logo space (top left corner) | +| `$scale` | `int` | `5` | * | Pixel size of a QR code module | +| `$imageTransparent` | `bool` | `true` | * | Toggle transparency (no jpeg support), QRGdImage and QRImagick only. The given `QROptions::$transparencyColor` is set as transparent | +| `$transparencyColor` | `mixed` | `null` | a valid GD or Imagick color value | Sets a transparency color for when `QROptions::$imageTransparent` is set to true. Defaults to `QROptions::$bgColor`. | +| `$pngCompression` | `int` | `-1` | `-1...9` | `imagepng()` compression level, -1 = auto | +| `$jpegQuality` | `int` | `85` | `0...100` | `imagejpeg()` quality | +| `$imagickFormat` | `string` | `'png'` | * | ImageMagick output type, see `Imagick::setType()` | +| `$cssClass` | `string` | `'qrcode'` | * | A common css class | +| `$markupDark` | `string` | `'#000'` | * | Markup substitute for dark (CSS value) | +| `$markupLight` | `string` | `'#fff'` | * | Markup substitute for light (CSS value) | +| `$svgAddXmlHeader` | `bool` | `true` | * | Whether to add an XML header line or not, e.g. to embed the SVG directly in HTML | +| `$svgOpacity` | `float` | `1.0` | `0...1` | SVG opacity | +| `$svgDefs` | `string` | `''` | * | Anything in the [``](https://developer.mozilla.org/docs/Web/SVG/Element/defs) tag | +| `$svgViewBoxSize` | `int\|null` | `null` | * | SVG viewBox size. A single integer number which defines width/height of the [viewBox attribute](https://css-tricks.com/scale-svg/#article-header-id-3) `viewBox="0 0 x x"`. | +| `$svgPreserveAspectRatio` | `string` | `'xMidYMid'` | * | See [preserveAspectRatio on MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio) | +| `$svgWidth` | `string\|null` | `null` | * | Optional "width" attribute with the specified value (note that the value is not checked!) | +| `$svgHeight` | `string\|null` | `null` | * | Optional "height" attribute with the specified value (note that the value is not checked!) | +| `$textDark` | `string` | `'🔴'` | * | String substitute for dark | +| `$textLight` | `string` | `'⭕'` | * | String substitute for light | +| `$fpdfMeasureUnit` | `string` | `'pt'` | * | Measurement unit for FPDF output: pt, mm, cm, in | +| `$readerUseImagickIfAvailable` | `bool` | `false` | * | Use Imagick (if available) when reading QR Codes | +| `$readerGrayscale` | `bool` | `false` | * | Grayscale the image before reading | +| `$readerIncreaseContrast` | `bool` | `false` | * | Increase the contrast before reading | diff --git a/docs/API-QROutputInterface.md b/docs/API-QROutputInterface.md new file mode 100644 index 000000000..2a5447754 --- /dev/null +++ b/docs/API-QROutputInterface.md @@ -0,0 +1,29 @@ +# `QROutputInterface` + +The full phpDocumentor API documentation can be found at [chillerlan.github.io/php-qrcode](https://chillerlan.github.io/php-qrcode/classes/chillerlan-QRCode-Output-QROutputInterface.html). + +## Methods + +| method | return | description | +|---------------------------------------|---------|---------------------------------------------------------------------| +| (static) `moduleValueIsValid($value)` | `bool` | Determines whether the given value is valid | +| `dump(string $file = null)` | `mixed` | Generates the output, optionally dumps it to a file, and returns it | + +## Constants + +| name | description | +|-------------------------|----------------------------------------------------| +| `MARKUP_HTML` | | +| `MARKUP_SVG` | | +| `GDIMAGE_PNG` | | +| `GDIMAGE_JPG` | | +| `GDIMAGE_GIF` | | +| `STRING_JSON` | | +| `STRING_TEXT` | | +| `IMAGICK` | | +| `FPDF` | | +| `EPS` | | +| `CUSTOM` | | +| `MODES` | Map of built-in output modes => class FQN | +| `DEFAULT_MODULE_VALUES` | Map of module type => default value | +| `LAYERNAMES` | Map of module type => readable name (for CSS etc.) | diff --git a/docs/Appendix-Glossary.md b/docs/Appendix-Glossary.md new file mode 100644 index 000000000..ab25e3d13 --- /dev/null +++ b/docs/Appendix-Glossary.md @@ -0,0 +1,306 @@ +# Terminology + +## QR Code + +A [*QR code*](https://en.wikipedia.org/wiki/QR_code) (quick-response code) 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. +QR Codes, more specifically, the popular *Model 2*, are internationally standardized in the ISO/IEC 18004. + + +## Matrix + +A QR symbol is arranged in a *matrix* consisting of an array of nominally square modules arranged in an overall square pattern. + +For ease of reference, module positions are defined by their row and column coordinates in the symbol, in the form `(x, y)` +where `x` designates the column (counting from left to right) and `y` the row (counting from the top downwards) in which +the module is located, with counting commencing at 0. Module `(0, 0)` is therefore located in the upper left corner of the symbol. + + +### Module + +A *module* represents a single square "pixel" (not to confuse with pixels in a raster image or screen) in the matrix. +A dark module is a binary one and a light module is a binary zero. + + +### Version + +The *version* of a QR symbol determines the side length of the matrix (and therefore the maximum capacity of code words), +ranging from 21×21 modules at version 1 to 177×177 modules at version 40; the module count increases in steps of 4 and can +be calculated by `4 * version + 17`. + +The maximum capacity for each version, mode and ECC level can be found in [this table (qrcode.com)](https://www.qrcode.com/en/about/version.html). + + +## Function Patterns + +### Finder Pattern + +The *Finder Pattern* shall consist of three identical Position Detection Patterns located at the upper left, upper right +and lower left corners of the symbol. + +Each Position Detection Pattern may be viewed as three superimposed concentric squares and is constructed of dark 7×7 modules, +light 5×5 modules and dark 3×3 modules. + +The symbol is preferentially encoded so that similar patterns have a low probability of being encountered elsewhere in the symbol, +enabling rapid identification of a possible QR Code symbol in the field of view. Identification of the three Position Detection +Patterns comprising the finder pattern then unambiguously defines the location and orientation of the symbol in the field of view. + +

+ Finder pattern +

+ + +### Alignment Pattern + +The *Alignment Pattern* is a fixed reference pattern in defined positions, which enables the decode software to +resynchronise the coordinate mapping of the modules in the event of moderate amounts of distortion of the image. + +Each Alignment Pattern may be viewed as three superimposed concentric squares and is constructed of dark 5×5 +modules, light 3×3 modules and a single central dark module. + +The number of Alignment Patterns depends on the symbol version, and they shall be placed in all Model 2 symbols of +version 2 or larger in positions defined in the specification. + +

+ Alignment Pattern +

+ + +### Timing Pattern + +The horizontal and vertical Timing Patterns respectively consist of a one module wide row or column of alternating +dark and light modules, commencing and ending with a dark module. The horizontal Timing Pattern runs across +row 6 of the symbol between the separators for the upper Position Detection Patterns; the vertical Timing Pattern +similarly runs down column 6 of the symbol between the separators for the left-hand Position Detection Patterns. +They enable the symbol density and version to be determined and provide datum positions for determining module +coordinates. + +

+ Timing Pattern +

+ + +### Separators + +A pattern of all light modules, one module wide, separating the Position Detection Patterns from the rest of the symbol. + +

+ Separators +

+ + +### Quiet Zone + +This is a region 4 modules wide which shall be free of all other markings, surrounding the symbol on all four sides. +Its nominal reflectance value shall be equal to that of the light modules. + +

+ Quiet Zone +

+ + +## Encoding Region + +This region shall contain the symbol characters representing data, those representing error correction codewords, +the Version Information and Format Information. + + +### Data + +This region contains the encoded data and error correction code blocks. Data bits are placed starting at the bottom-right of +the matrix and proceeding upward in a column that is 2 modules wide. When the column reaches the top, the next 2-module column +starts immediately to the left of the previous column and continues downward. Whenever the current column reaches the edge of +the matrix, move on to the next 2-module column and change direction. If a function pattern or reserved area is encountered, +the data bit is placed in the next unused module. +(see [wikipedia QR code - Encoding](https://en.wikipedia.org/wiki/QR_code#Encoding) and [thonky.com - QR Code Tutorial](https://www.thonky.com/qr-code-tutorial/module-placement-matrix#step-6-place-the-data-bits)) + +

+ Data +

+ + +### Version Information + +The Version Information is an 18 bit sequence containing 6 data bits, with 12 error correction bits calculated using the (18, 6) +[BCH code](https://en.wikipedia.org/wiki/BCH_code) which contains the version number. + +

+ Version Information +

+ + +### Format Information + +The Format Information is a 15 bit sequence containing 5 data bits, with 10 error correction bits calculated using the (15, 5) BCH code. +It contains information on the error correction level applied to the symbol and on the masking pattern used, +essential to enable the remainder of the encoding region to be decoded. + +

+ Format Information +

+ + +### Darkmodule + +The module in position `(4 * version + 9, 8)` shall always be dark and does not form part of the Format Information. + +

+ Darkmodule +

+ + +## Mode + +The *mode* is the method of representing a defined character set as a bit string, with a *mode indicator*, a four-bit identifier indicating in which mode the next data sequence is encoded. + +| Mode | Indicator | Description | +|-------------------------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Numeric | `0001` | Numeric encoding, 10 bits per 3 digits | +| Alphanumeric | `0010` | Alphanumeric encoding, 11 bits per 2 characters | +| Byte | `0100` | Byte encoding, 8 bits per character | +| Kanji | `1000` | [Kanji](https://en.wikipedia.org/wiki/Kanji) encoding (Japanese, [Shift-JIS](https://en.wikipedia.org/wiki/Shift_JIS)), 13 bits per character | +| Hanzi* | `1101` | [Hanzi](https://en.wikipedia.org/wiki/Chinese_characters) encoding (simplified Chinese, [GB2312/GB18030](https://en.wikipedia.org/wiki/GB_18030)), 13 bits per character | +| Structured append | `0011` | used to split a message across multiple (up to 16) QR symbols | +| ECI | `0111` | [Extended Channel Interpretation](https://en.wikipedia.org/wiki/Extended_Channel_Interpretation) (select alternate character set or encoding) | +| FNC1 in first position | `0101` | see [Code 128](https://en.wikipedia.org/wiki/Code_128), also [zxing/issues/1373](https://github.com/zxing/zxing/issues/1373) | +| FNC1 in second position | `1001` | | +| Terminator | `0000` | End of message | + +* Hanzi mode is not part of the ISO specification, but the Chinese standard [GB/T 18284](https://www.chinesestandard.net/PDF/English.aspx/GBT18284-2000) + + +### Segment + +Each segment consists of the 4 bit mode indicator followed by the data bit stream, where the content of the bit stream can vary depending on the mode: + +| Mode | Bit stream contents | +|-------------------------|--------------------------------------------------------------------------------------------------------------| +| Numeric | \[ `0001` : 4 ] \[ Character Count Indicator : variable ] \[ Data Bit Stream : 3 1⁄3 × charcount ] | +| Alphanumeric | \[ `0010` : 4 ] \[ Character Count Indicator : variable ] \[ Data Bit Stream : 5 1⁄2 × charcount ] | +| Byte | \[ `0100` : 4 ] \[ Character Count Indicator : variable ] \[ Data Bit Stream : 8 × charcount ] | +| Kanji | \[ `1000` : 4 ] \[ Character Count Indicator : variable ] \[ Data Bit Stream : 13 × charcount ] | +| Hanzi | \[ `1101` : 4 ] \[ Character Count Indicator : variable ] \[ Data Bit Stream : 13 × charcount ] | +| Structured append | \[ `0011` : 4 ] \[ Symbol Position : 4 ] \[ Total Symbols : 4 ] \[ Parity : 8 ] | +| ECI | \[ `0111` : 4 ] \[ ECI Assignment number : variable ] | +| FNC1 in first position | \[ `0101` : 4 ] \[ Numeric/Alphanumeric/Byte/Kanji/Hanzi payload : variable ] | +| FNC1 in second position | \[ `1001` : 4 ] \[ Application Indicator : 8 ] \[ Numeric/Alphanumeric/Byte/Kanji/Hanzi payload : variable ] | +| Terminator | \[ `0000` : 4 ] | + +The lenght of the Character Count Indicator for Numeric/Alphanumeric/Byte/Kanji/Hanzi varies, depending on the version: + +| Mode | Version 1-9 | Version 10-26 | Version 27-40 | +|--------------|-------------|---------------|---------------| +| Numeric | 10 | 12 | 14 | +| Alphanumeric | 9 | 11 | 13 | +| Byte | 8 | 16 | 16 | +| Kanji/Hanzi | 8 | 10 | 12 | + + +### Extended Channel Interpretation (ECI) + +[Extended Channel Interpretation](https://en.wikipedia.org/wiki/Extended_Channel_Interpretation) can be used to indicate an +alternate character encoding for the following Byte segment (by default, ISO-8859-1 "Latin-1"). + +An ECI segment starts with the 4 bit indicator `0111` followed by the ECI Assignment number (8, 16 or 24 bits), +followed by a Byte segment (`0100` ...) where the contents are encoded according to the preceding ECI ID. + +The lenght of the ECI Assignment number depends on the given encoding ID: + +| ID | length (bits) | +|----------------|---------------| +| 0 - 127 | 8 | +| 128 - 16383 | 16 | +| 16384 - 999999 | 24 | + + +### Mixed Mode + +Encoding modes can be mixed as needed within a QR symbol in order to optimize data usage. +Each segment of data is encoded in the appropriate mode, with the basic structure +*Mode Indicator / Character Count Indicator / Data* and followed immediately by the Mode Indicator commencing the next segment. + +\[ Mode Indicator 1 ]\[ Mode bitstream 1 ]
+...
+\[ Mode Indicator n ]\[ Mode bitstream n ]
+...
+\[ `0000` End of message (Terminator) ] + + +## ECC (Error Correction Coding) + +QR codes use [Reed–Solomon error correction](https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction) that allow QR code readers to detect and correct errors. +A detailed breakdown of the process can be found at [thonky.com - QR Code Tutorial](https://www.thonky.com/qr-code-tutorial/error-correction-coding). + + +### ECC Level + +The number of data versus error correction bytes within each block depends on the version of the QR symbol and the error +correction level. The higher the error correction level, the less storage capacity. The following table lists the approximate +error correction capability at each of the four levels: + +| Level | Short | Capacity | Indicator | +|----------|-------|----------|-----------| +| Low | L | 7% | `01` | +| Medium | M | 15% | `00` | +| Quartile | Q | 25% | `11` | +| High | H | 30% | `10` | + + +### Maximum data capacity + +The maximum data capacity of a QR Code at version 40 for each ECC level and mode is shown in the following table: + +| ECC | max. bits | Numeric | Alphanumeric | Binary | Kanji/Hanzi * | +|-----|-----------|---------|--------------|--------|--------------------------| +| L | 23648 | 7089 | 4296 | 2953 | 1817 | +| M | 18672 | 5596 | 3391 | 2331 | 1435 | +| Q | 13328 | 3993 | 2420 | 1663 | 1024 | +| H | 10208 | 3057 | 1852 | 1273 | 784 | + +* Hanzi mode stores one character less than Kanji as it uses an additional subset indicator of 4 bits length. + + +## Data masking + +Masking is the process of XORing the bit pattern in the encoding region with a masking pattern to provide a symbol with more +evenly balanced numbers of dark and light modules and reduced occurrence of patterns which would interfere with fast processing of the image. + + +### Evaluation + +The mask pattern evaluation is done for each of the 8 mask patterns, the pattern with the lowest penalty score shall be used for the final output. +During the evaluation, 4 rules are applied to get the penalty score: + +- find repetitive cells with the same color Example: 00000 or 11111 (horizontal and vertical). +- find 2×2 blocks with the same color +- find consecutive runs of 1:1:3:1:1:4 starting with black, or 4:1:1:3:1:1 starting with white +- calculate the ratio of dark cells and give increasing penalty if the ratio is far from 50% + +### Mask pattern + +| Pattern | Mask* | Example | +|---------|---------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `000` | `(x + y) mod 2 = 0` | Mask pattern 000 | +| `001` | `y mod 2 = 0` | Mask pattern 001 | +| `010` | `x mod 3 = 0` | Mask pattern 010 | +| `011` | `(x + y) mod 3 = 0` | Mask pattern 011 | +| `100` | `((y intdiv 2) + (x intdiv 3)) mod 2 = 0` | Mask pattern 100 | +| `101` | `(x y) mod 2 + (x y) mod 3 = 0`
or:
`(x y) mod 6 = 0` | Mask pattern 101 | +| `110` | `((x y) mod 2 + (x y) mod 3) mod 2 = 0`
or:
`(x y) mod 6 < 3` | Mask pattern 110 | +| `111` | `((x y) mod 3 + (x + y) mod 2) mod 2 = 0`
or:
`(x + y + (x y) mod 3) mod 2 = 0` | Mask pattern 111 | + +* where `x` = column (width) and `y` = row (height), with `x,y = 0,0` for the top left module
+ + +## Reflectance + +Symbols are intended to be read when either dark on light or light on dark. +The International Standard (ISO/IEC 18004) is based on dark images on a light background (example on the left), +reflectance reversal therefore means a light image on dark background (example on the right). + +

+ Normal reflectance + Reversed reflectance +

diff --git a/docs/Readme.md b/docs/Readme.md index 8098db98a..75632cd63 100644 --- a/docs/Readme.md +++ b/docs/Readme.md @@ -19,8 +19,9 @@ Requirements: - [Sphinx RTD theme](https://pypi.org/project/sphinx-rtd-theme/) >= 1.2 - [MyST Parser](https://myst-parser.readthedocs.io/en/latest/intro.html) >= 2.0 (see [Sphinx Markdown configuration](https://www.sphinx-doc.org/en/master/usage/markdown.html#markdown)) +Follow these steps to create the user manual: -- to install all in one go, run: `pip install sphinx myst-parser sphinx-rtd-theme` +- install Sphinx: `pip install sphinx myst-parser sphinx-rtd-theme` - run in the `/docs` (this) directory: - on Windows: `.\make.bat html` (make sure `sphinx-build.exe` is in `PATH`) - on Linux: `make html` @@ -75,6 +76,7 @@ The markdown sources for the [Read the Docs online manual](https://php-qrcode.re - [`QROptions`](./API-QROptions.md) - [`QROutputInterface`](./API-QROutputInterface.md) - [`QRMatrix`](./API-QRMatrix.md) +- [`DecoderResult`](./API-DecoderResult.md) ### Appendix diff --git a/docs/Usage-Overview.md b/docs/Usage-Overview.md index 5c8cea390..2b656bcb5 100644 --- a/docs/Usage-Overview.md +++ b/docs/Usage-Overview.md @@ -1,32 +1,39 @@ # Overview +A PHP QR Code generator based on the [implementation by Kazuhiko Arase](https://github.com/kazuhikoarase/qrcode-generator), namespaced, cleaned up, improved and other stuff.
+It also features a QR Code reader based on a [PHP port](https://github.com/khanamiryan/php-qrcode-detector-decoder) of the [ZXing library](https://github.com/zxing/zxing). + + ## Features - Creation of [Model 2 QR Codes](https://www.qrcode.com/en/codes/model12.html), [Version 1 to 40](https://www.qrcode.com/en/about/version.html) - [ECC Levels](https://www.qrcode.com/en/about/error_correction.html) L/M/Q/H supported - Mixed mode support (encoding modes can be combined within a QR symbol). Supported modes: - - numeric - - alphanumeric - - 8-bit binary - - 13-bit double-byte kanji (Japanese, Shift-JIS) and hanzi (simplified Chinese, GB2312/GB18030) as [defined in GBT18284-2000](https://www.chinesestandard.net/PDF/English.aspx/GBT18284-2000) + - numeric + - alphanumeric + - 8-bit binary + - 13-bit double-byte: + - kanji (Japanese, Shift-JIS) + - hanzi (simplified Chinese, GB2312/GB18030) as [defined in GBT18284-2000](https://www.chinesestandard.net/PDF/English.aspx/GBT18284-2000) - Flexible, easily extensible output modules, built-in support for the following output formats: - - [GdImage](https://www.php.net/manual/book.image) - - [ImageMagick](https://www.php.net/manual/book.imagick) - - Markup types: SVG, HTML, etc. - - String types: JSON, plain text, etc. - - Encapsulated Postscript (EPS) - - PDF via [FPDF](https://github.com/setasign/fpdf) + - [GdImage](https://www.php.net/manual/book.image) + - [ImageMagick](https://www.php.net/manual/book.imagick) + - Markup types: SVG, HTML, etc. + - String types: JSON, plain text, etc. + - Encapsulated Postscript (EPS) + - PDF via [FPDF](https://github.com/setasign/fpdf) - QR Code reader (via GD and ImageMagick) ## Requirements + - PHP 7.4+ - - [`ext-mbstring`](https://www.php.net/manual/book.mbstring.php) - - optional: - - [`ext-fileinfo`](https://www.php.net/manual/book.fileinfo.php) (required by `QRImagick` output) - - [`ext-gd`](https://www.php.net/manual/book.image) - - [`ext-imagick`](https://github.com/Imagick/imagick) with [ImageMagick](https://imagemagick.org) installed - - [`setasign/fpdf`](https://github.com/setasign/fpdf) for the PDF output module + - [`ext-mbstring`](https://www.php.net/manual/book.mbstring.php) + - optional: + - [`ext-fileinfo`](https://www.php.net/manual/book.fileinfo.php) (required by `QRImagick` output) + - [`ext-gd`](https://www.php.net/manual/book.image) + - [`ext-imagick`](https://github.com/Imagick/imagick) with [ImageMagick](https://imagemagick.org) installed + - [`setasign/fpdf`](https://github.com/setasign/fpdf) for the PDF output module For the QR Code reader, either `ext-gd` or `ext-imagick` is required! @@ -34,23 +41,35 @@ For the QR Code reader, either `ext-gd` or `ext-imagick` is required! ## Framework Integration - Drupal: - - [Two-factor Authentication `tfa`](https://www.drupal.org/project/tfa) (Drupal 8+) - - [Google Authenticator Login `ga_login`](https://www.drupal.org/project/ga_login) (deprecated, Drupal 7) + - [Two-factor Authentication `tfa`](https://www.drupal.org/project/tfa) (Drupal 8+) + - [Google Authenticator Login `ga_login`](https://www.drupal.org/project/ga_login) (deprecated, Drupal 7) - Symfony - - [phpqrcode-bundle](https://github.com/jonasarts/phpqrcode-bundle) + - [phpqrcode-bundle](https://github.com/jonasarts/phpqrcode-bundle) - WordPress: - - [wp-two-factor-auth](https://github.com/sjinks/wp-two-factor-auth) - - [simple-2fa](https://wordpress.org/plugins/simple-2fa/) - - [floating-share-button](https://github.com/qriouslad/floating-share-button) + - [wp-two-factor-auth](https://github.com/sjinks/wp-two-factor-auth) + - [simple-2fa](https://wordpress.org/plugins/simple-2fa/) + - [floating-share-button](https://github.com/qriouslad/floating-share-button) - WoltLab Suite - - [two-step-verification](http://pluginstore.woltlab.com/file/3007-two-step-verification/) + - [two-step-verification](http://pluginstore.woltlab.com/file/3007-two-step-verification/) - other uses: - - [dependents](https://github.com/chillerlan/php-qrcode/network/dependents) / [packages](https://github.com/chillerlan/php-qrcode/network/dependents?dependent_type=PACKAGE) - - [Appwrite](https://github.com/appwrite/appwrite) - - [Cachet](https://github.com/CachetHQ/Cachet) - - [GÉANT CAT](https://github.com/GEANT/CAT) - - [openITCOCKPIT](https://github.com/it-novum/openITCOCKPIT) - - [twill](https://github.com/area17/twill) - - [Elefant CMS](https://github.com/jbroadway/elefant) + - [dependents](https://github.com/chillerlan/php-qrcode/network/dependents) / [packages](https://github.com/chillerlan/php-qrcode/network/dependents?dependent_type=PACKAGE) + - [Appwrite](https://github.com/appwrite/appwrite) + - [Cachet](https://github.com/CachetHQ/Cachet) + - [GÉANT CAT](https://github.com/GEANT/CAT) + - [openITCOCKPIT](https://github.com/it-novum/openITCOCKPIT) + - [twill](https://github.com/area17/twill) + - [Elefant CMS](https://github.com/jbroadway/elefant) - Articles: - - [Twilio: How to Create a QR Code in PHP](https://www.twilio.com/blog/create-qr-code-in-php) (featuring v4.3.x) + - [Twilio: How to Create a QR Code in PHP](https://www.twilio.com/blog/create-qr-code-in-php) (featuring v4.3.x) + + +## 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-core](https://github.com/chillerlan/php-oauth-core) - an OAuth 1/2 client library along with a bunch of [providers](https://github.com/chillerlan/php-oauth-providers) +- [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 diff --git a/docs/index.rst b/docs/index.rst index 6c485d687..6cf2ab22d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,9 +17,20 @@ This work is licensed under the Creative Commons Attribution 4.0 International ( Usage-Quickstart Usage-Advanced-usage +.. toctree:: + :maxdepth: 3 + :caption: Public API + + API-QRCode + API-QROptions + API-QROutputInterface + API-QRMatrix + API-DecoderResult + .. toctree:: :maxdepth: 3 :caption: Appendix + Appendix-Glossary Appendix-License