Files
php-qrcode/Customizing/Custom-output-interface.html

614 lines
60 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Custom QROutputInterface &mdash; PHP-QRCode main
Manual</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=9edc463e" />
<script src="../_static/jquery.js?v=5d32c60e"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="../_static/documentation_options.js?v=a8da1a53"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="QREps" href="../Built-In-Output/QREps.html" />
<link rel="prev" title="QROutputAbstract" href="QROutputAbstract.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home">
PHP-QRCode
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Usage</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../Usage/Overview.html">Overview</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Overview.html#features">Features</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Overview.html#requirements">Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Overview.html#framework-integration">Framework Integration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Overview.html#shameless-advertising">Shameless advertising</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Usage/Installation.html">Installation</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Installation.html#installation-with-composer">Installation with Composer</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Installation.html#composer-json">composer.json</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../Usage/Installation.html#version-switch">Version switch</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Installation.html#terminal">Terminal</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Installation.html#manual-installation">Manual installation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Installation.html#can-i-use-this-library-without-using-composer">Can I use this library without using composer?</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Installation.html#supported-php-versions-extension-requirements">Supported PHP versions &amp; extension requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Installation.html#imagemagick">ImageMagick</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Usage/Quickstart.html">Quickstart</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Quickstart.html#import-the-library">Import the library</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Quickstart.html#create-your-first-qr-code">Create your first QR Code</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Quickstart.html#configuration">Configuration</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Quickstart.html#notes">Notes</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Usage/Advanced-usage.html">Advanced usage</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Advanced-usage.html#configuration-via-qroptions">Configuration via <code class="docutils literal notranslate"><span class="pre">QROptions</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#supply-an-iterable-of-options">Supply an <code class="docutils literal notranslate"><span class="pre">iterable</span></code> of options</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#load-and-save-options-from-to-json">Load and save options from/to JSON</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#extending-the-qroptions-class">Extending the <code class="docutils literal notranslate"><span class="pre">QROptions</span></code> class</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Advanced-usage.html#qrcode-methods"><code class="docutils literal notranslate"><span class="pre">QRCode</span></code> methods</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#render-a-qrmatrix-instance">Render a <code class="docutils literal notranslate"><span class="pre">QRMatrix</span></code> instance</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#mixed-mode">Mixed mode</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Advanced-usage.html#common-output-options">Common output options</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#save-to-file">Save to file</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#base64-uri-output">Base64 URI output</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Usage/Advanced-usage.html#return-the-image-resource">Return the image resource</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Usage/Configuration-settings.html">Configuration settings</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#version">version</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#versionmin">versionMin</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#versionmax">versionMax</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#ecclevel">eccLevel</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#maskpattern">maskPattern</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#addquietzone">addQuietzone</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#quietzonesize">quietzoneSize</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#outputinterface">outputInterface</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#returnresource">returnResource</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#cachefile">cachefile</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#outputbase64">outputBase64</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#eol">eol</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#bgcolor">bgColor</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#invertmatrix">invertMatrix</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#drawlightmodules">drawLightModules</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#drawcircularmodules">drawCircularModules</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#circleradius">circleRadius</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#keepassquare">keepAsSquare</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#connectpaths">connectPaths</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#excludefromconnect">excludeFromConnect</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#modulevalues">moduleValues</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#addlogospace">addLogoSpace</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#logospacewidth">logoSpaceWidth</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#logospaceheight">logoSpaceHeight</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#logospacestartx">logoSpaceStartX</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#logospacestarty">logoSpaceStartY</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#scale">scale</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#imagetransparent">imageTransparent</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#transparencycolor">transparencyColor</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#quality">quality</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#gdimageuseupscale">gdImageUseUpscale</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#imagickformat">imagickFormat</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#cssclass">cssClass</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#svgaddxmlheader">svgAddXmlHeader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#svgdefs">svgDefs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#svgpreserveaspectratio">svgPreserveAspectRatio</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#svgusefillattributes">svgUseFillAttributes</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#textlinestart">textLineStart</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#jsonflags">jsonFlags</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#fpdfmeasureunit">fpdfMeasureUnit</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#xmlstylesheet">xmlStylesheet</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#readeruseimagickifavailable">readerUseImagickIfAvailable</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#readergrayscale">readerGrayscale</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#readerinvertcolors">readerInvertColors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Configuration-settings.html#readerincreasecontrast">readerIncreaseContrast</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Usage/Reading-QRCodes.html">Reading QR Codes</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Reading-QRCodes.html#basic-usage">Basic usage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Reading-QRCodes.html#the-luminancesourceinterface">The <code class="docutils literal notranslate"><span class="pre">LuminanceSourceInterface</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Reading-QRCodes.html#the-decoder">The <code class="docutils literal notranslate"><span class="pre">Decoder</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Reading-QRCodes.html#general-considerations">General considerations</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Usage/Logos.html">Logos and logo space</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Logos.html#info">Info</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Usage/Logos.html#adding-a-logo-space">Adding a logo space</a></li>
</ul>
</li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Customizing output</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Module-Values.html">Module values</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Module-Values.html#basics">Basics</a></li>
<li class="toctree-l2"><a class="reference internal" href="Module-Values.html#assigning-values">Assigning values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Module-Values.html#handling-in-your-own-qroutputinterface">Handling in your own <code class="docutils literal notranslate"><span class="pre">QROutputInterface</span></code></a><ul>
<li class="toctree-l3"><a class="reference internal" href="Module-Values.html#setting-module-values">Setting module values</a></li>
<li class="toctree-l3"><a class="reference internal" href="Module-Values.html#using-the-module-values">Using the module values</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="QROutputAbstract.html"><code class="docutils literal notranslate"><span class="pre">QROutputAbstract</span></code></a><ul>
<li class="toctree-l2"><a class="reference internal" href="QROutputAbstract.html#properties">Properties</a><ul>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#options-and-matrix"><code class="docutils literal notranslate"><span class="pre">$options</span></code> and <code class="docutils literal notranslate"><span class="pre">$matrix</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#modulecount-scale-and-length"><code class="docutils literal notranslate"><span class="pre">$moduleCount</span></code>, <code class="docutils literal notranslate"><span class="pre">$scale</span></code> and <code class="docutils literal notranslate"><span class="pre">$length</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#modulevalues"><code class="docutils literal notranslate"><span class="pre">$moduleValues</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#copies-of-qroptions-values">Copies of <code class="docutils literal notranslate"><span class="pre">QROptions</span></code> values</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="QROutputAbstract.html#methods">Methods</a><ul>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#setmodulevalues"><code class="docutils literal notranslate"><span class="pre">setModuleValues()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#modulevalueisvalid"><code class="docutils literal notranslate"><span class="pre">moduleValueIsValid()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#preparemodulevalue"><code class="docutils literal notranslate"><span class="pre">prepareModuleValue()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#getdefaultmodulevalue"><code class="docutils literal notranslate"><span class="pre">getDefaultModuleValue()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#getmodulevalue-and-getmodulevalueat"><code class="docutils literal notranslate"><span class="pre">getModuleValue()</span></code> and <code class="docutils literal notranslate"><span class="pre">getModuleValueAt()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#setmatrixdimensions"><code class="docutils literal notranslate"><span class="pre">setMatrixDimensions()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#getoutputdimensions"><code class="docutils literal notranslate"><span class="pre">getOutputDimensions()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#collectmodules"><code class="docutils literal notranslate"><span class="pre">collectModules()</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="QROutputAbstract.html#savetofile-and-tobase64datauri"><code class="docutils literal notranslate"><span class="pre">saveToFile()</span></code> and <code class="docutils literal notranslate"><span class="pre">toBase64DataURI()</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Custom <code class="docutils literal notranslate"><span class="pre">QROutputInterface</span></code></a><ul>
<li class="toctree-l2"><a class="reference internal" href="#class-skeleton">Class skeleton</a></li>
<li class="toctree-l2"><a class="reference internal" href="#module-values">Module values</a></li>
<li class="toctree-l2"><a class="reference internal" href="#transform-the-output">Transform the output</a></li>
<li class="toctree-l2"><a class="reference internal" href="#run-the-custom-output">Run the custom output</a></li>
<li class="toctree-l2"><a class="reference internal" href="#summary">Summary</a></li>
</ul>
</li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Built-In Output Classes</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QREps.html">QREps</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QREps.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QREps.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QREps.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRFpdf.html">QRFpdf</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRFpdf.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRFpdf.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRFpdf.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRGdImage.html">QRGdImage</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRGdImage.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRGdImage.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRGdImage.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRImagick.html">QRImagick</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRImagick.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRImagick.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRImagick.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRInterventionImage.html">QRInterventionImage</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRInterventionImage.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRInterventionImage.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRInterventionImage.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRMarkupHTML.html">QRMarkupHTML</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupHTML.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupHTML.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupHTML.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRMarkupSVG.html">QRMarkupSVG</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupSVG.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupSVG.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupSVG.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRMarkupXML.html">QRMarkupXML</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupXML.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupXML.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRMarkupXML.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRStringJSON.html">QRStringJSON</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRStringJSON.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRStringJSON.html#previous-functionality">Previous functionality</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRStringJSON.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRStringJSON.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Built-In-Output/QRStringText.html">QRStringText</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRStringText.html#example">Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRStringText.html#additional-methods">Additional methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Built-In-Output/QRStringText.html#options-that-affect-this-class">Options that affect this class</a></li>
</ul>
</li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Appendix</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../Appendix/Terminology.html">Terminology</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#qr-code">QR Code</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#matrix">Matrix</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#module">Module</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#version">Version</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#function-patterns">Function Patterns</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#finder-pattern">Finder Pattern</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#alignment-pattern">Alignment Pattern</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#timing-pattern">Timing Pattern</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#separators">Separators</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#quiet-zone">Quiet Zone</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#encoding-region">Encoding Region</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#data">Data</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#version-information">Version Information</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#format-information">Format Information</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#darkmodule">Darkmodule</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#mode">Mode</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#segment">Segment</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#extended-channel-interpretation-eci">Extended Channel Interpretation (ECI)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#mixed-mode">Mixed Mode</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#ecc-error-correction-coding">ECC (Error Correction Coding)</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#ecc-level">ECC Level</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#maximum-data-capacity">Maximum data capacity</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#data-masking">Data masking</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#evaluation">Evaluation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/Terminology.html#mask-pattern">Mask pattern</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Terminology.html#reflectance">Reflectance</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Appendix/URI-Content.html">Popular content and URI schemes</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#url-https">URL <code class="docutils literal notranslate"><span class="pre">https</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#e-mail-mailto">E-Mail <code class="docutils literal notranslate"><span class="pre">mailto</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#phone-numbers-tel">Phone numbers <code class="docutils literal notranslate"><span class="pre">tel</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#geo-coordinates-geo">Geo Coordinates <code class="docutils literal notranslate"><span class="pre">geo</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#mobile-authenticators-otpauth">Mobile Authenticators <code class="docutils literal notranslate"><span class="pre">otpauth</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#wireless-network-configuration">Wireless Network configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#contact-information-vcard">Contact information: vCard</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#calendar-events-vcalendar-and-icalendar">Calendar Events: vCalendar and iCalendar</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#credit-transfer">Credit Transfer</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/URI-Content.html#sepa-european-payments-council">SEPA (European Payments Council)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../Appendix/URI-Content.html#pix-banco-central-do-brasil">Pix (Banco Central do Brasil)</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/URI-Content.html#see-also">See also</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Appendix/Performance-considerations.html">Performance considerations</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Performance-considerations.html#version">Version</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Performance-considerations.html#ecc-level">Ecc level</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Performance-considerations.html#data-mode">Data mode</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Performance-considerations.html#mask-pattern">Mask pattern</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Performance-considerations.html#output">Output</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Appendix/Contribute.html">How to contribute</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Contribute.html#questions-and-issues">Questions and issues</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Contribute.html#bug-reports">Bug reports</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Contribute.html#pull-requests-and-bug-fixes">Pull requests and bug fixes</a></li>
<li class="toctree-l2"><a class="reference internal" href="../Appendix/Contribute.html#documentation">Documentation</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../Appendix/License.html">License</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">PHP-QRCode</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active">Custom <code class="docutils literal notranslate"><span class="pre">QROutputInterface</span></code></li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/chillerlan/php-qrcode/blob/main/docs/Customizing/Custom-output-interface.md" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="custom-qroutputinterface">
<h1>Custom <code class="docutils literal notranslate"><span class="pre">QROutputInterface</span></code><a class="headerlink" href="#custom-qroutputinterface" title="Link to this heading"></a></h1>
<p>Lets suppose that we want to create our own output interface because theres no built-in output class that supports the format we need for our application.
In this example well create a string output class that outputs the coordinates for each module, separated by module type.</p>
<section id="class-skeleton">
<h2>Class skeleton<a class="headerlink" href="#class-skeleton" title="Link to this heading"></a></h2>
<p>Well start with a skeleton that extends <code class="docutils literal notranslate"><span class="pre">QROutputAbstract</span></code> and implements the methods that are required by <code class="docutils literal notranslate"><span class="pre">QROutputInterface</span></code>:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyCustomOutput</span> <span class="k">extends</span> <span class="nx">QROutputAbstract</span><span class="p">{</span>
<span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="nf">moduleValueIsValid</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span><span class="o">:</span><span class="nx">bool</span><span class="p">{}</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">prepareModuleValue</span><span class="p">(</span><span class="nv">$value</span><span class="p">){}</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">getDefaultModuleValue</span><span class="p">(</span><span class="nx">bool</span> <span class="nv">$isDark</span><span class="p">){}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">dump</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$file</span> <span class="o">=</span> <span class="k">null</span><span class="p">){}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="module-values">
<h2>Module values<a class="headerlink" href="#module-values" title="Link to this heading"></a></h2>
<p>The validator should check whether the given input value and range is valid for the output class and if it can be given to the <code class="docutils literal notranslate"><span class="pre">QROutputAbstract::prepareModuleValue()</span></code> method.
For example in the built-in GD output it would check if the value is an array that has a minimum of 3 elements (for RGB), each of which is numeric.</p>
<p>In this example well accept string values, the characters <code class="docutils literal notranslate"><span class="pre">a-z</span></code> (case-insensitive) and a hyphen <code class="docutils literal notranslate"><span class="pre">-</span></code>:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span> <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="nf">moduleValueIsValid</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span><span class="o">:</span><span class="nx">bool</span><span class="p">{</span>
<span class="k">return</span> <span class="nb">is_string</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nb">preg_match</span><span class="p">(</span><span class="s1">&#39;/^[a-z-]+$/i&#39;</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span> <span class="o">===</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>To prepare the final module substitute, we should transform the given (validated) input value in a way so that it can be accessed without any further calls or transformation.
In the built-in output for example this means it would return an <code class="docutils literal notranslate"><span class="pre">ImagickPixel</span></code> instance or the integer value returned by <code class="docutils literal notranslate"><span class="pre">imagecolorallocate()</span></code> on the current <code class="docutils literal notranslate"><span class="pre">GdImage</span></code> instance.</p>
<p>For our example, well lowercase the validated string:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span> <span class="k">protected</span> <span class="k">function</span> <span class="nf">prepareModuleValue</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="k">return</span> <span class="nb">strtolower</span><span class="p">(</span><span class="nv">$value</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Finally, we need to provide a default value for dark and light, we can call <code class="docutils literal notranslate"><span class="pre">prepareModuleValue()</span></code> here if necessary.
Well return an empty string <code class="docutils literal notranslate"><span class="pre">''</span></code> as were going to use the <code class="docutils literal notranslate"><span class="pre">QROutputInterface::LAYERNAMES</span></code> constant for non-existing values
(returning <code class="docutils literal notranslate"><span class="pre">null</span></code> would run into an exception in <code class="docutils literal notranslate"><span class="pre">QROutputAbstract::getModuleValue()</span></code>).</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span> <span class="k">protected</span> <span class="k">function</span> <span class="nf">getDefaultModuleValue</span><span class="p">(</span><span class="nx">bool</span> <span class="nv">$isDark</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="transform-the-output">
<h2>Transform the output<a class="headerlink" href="#transform-the-output" title="Link to this heading"></a></h2>
<p>In our example, we want to collect the modules by type and have the collections listed under a header for each type.
In order to do so, we need to collect the modules per <code class="docutils literal notranslate"><span class="pre">$M_TYPE</span></code> before we can render the final output.</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span> <span class="k">public</span> <span class="k">function</span> <span class="nf">dump</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$file</span> <span class="o">=</span> <span class="k">null</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="nv">$collections</span> <span class="o">=</span> <span class="p">[];</span>
<span class="c1">// loop over the matrix and collect the modules per layer</span>
<span class="k">foreach</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">matrix</span><span class="o">-&gt;</span><span class="na">getMatrix</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$y</span> <span class="o">=&gt;</span> <span class="nv">$row</span><span class="p">){</span>
<span class="k">foreach</span><span class="p">(</span><span class="nv">$row</span> <span class="k">as</span> <span class="nv">$x</span> <span class="o">=&gt;</span> <span class="nv">$M_TYPE</span><span class="p">){</span>
<span class="nv">$collections</span><span class="p">[</span><span class="nv">$M_TYPE</span><span class="p">][]</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">module</span><span class="p">(</span><span class="nv">$x</span><span class="p">,</span> <span class="nv">$y</span><span class="p">,</span> <span class="nv">$M_TYPE</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// build the final output</span>
<span class="nv">$out</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">foreach</span><span class="p">(</span><span class="nv">$collections</span> <span class="k">as</span> <span class="nv">$M_TYPE</span> <span class="o">=&gt;</span> <span class="nv">$collection</span><span class="p">){</span>
<span class="nv">$name</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getModuleValue</span><span class="p">(</span><span class="nv">$M_TYPE</span><span class="p">)</span> <span class="o">?:</span> <span class="nv">$this</span><span class="o">::</span><span class="na">LAYERNAMES</span><span class="p">[</span><span class="nv">$M_TYPE</span><span class="p">]);</span>
<span class="c1">// the section header</span>
<span class="nv">$out</span><span class="p">[]</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;%s (%012b)</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$name</span><span class="p">,</span> <span class="nv">$M_TYPE</span><span class="p">);</span>
<span class="c1">// the list of modules</span>
<span class="nv">$out</span><span class="p">[]</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">implode</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$collection</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nb">implode</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$out</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Speaking of option settings, theres also <code class="docutils literal notranslate"><span class="pre">QROptions::$connectPaths</span></code> which we havent taken care of yet - the good news is that we dont need to as it is already implemented!
Well modify the above <code class="docutils literal notranslate"><span class="pre">dump()</span></code> method to use <code class="docutils literal notranslate"><span class="pre">QROutputAbstract::collectModules()</span></code> instead.</p>
<p>The module collector calls a method <code class="docutils literal notranslate"><span class="pre">moduleTransform()</span></code> internally, which is called with 4 parameters:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">$x</span></code> : current column</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">$y</span></code> : current row</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">$M_TYPE</span></code> : field value</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">$M_TYPE_LAYER</span></code>: (possibly modified) field value that acts as layer id</p></li>
</ul>
<p>We## introduce another method that handles the module rendering, which incooperates handling of the <code class="docutils literal notranslate"><span class="pre">QROptions::$drawLightModules</span></code> setting:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span> <span class="k">protected</span> <span class="k">function</span> <span class="nf">moduleTransform</span><span class="p">(</span><span class="nx">int</span> <span class="nv">$x</span><span class="p">,</span> <span class="nx">int</span> <span class="nv">$y</span><span class="p">,</span> <span class="nx">int</span> <span class="nv">$M_TYPE</span><span class="p">,</span> <span class="nx">int</span> <span class="nv">$M_TYPE_LAYER</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">drawLightModules</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">matrix</span><span class="o">-&gt;</span><span class="na">isDark</span><span class="p">(</span><span class="nv">$M_TYPE</span><span class="p">)){</span>
<span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s1">&#39;x: %s, y: %s&#39;</span><span class="p">,</span> <span class="nv">$x</span><span class="p">,</span> <span class="nv">$y</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>This is our final output method then:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span> <span class="k">public</span> <span class="k">function</span> <span class="nf">dump</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$file</span> <span class="o">=</span> <span class="k">null</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="nv">$collections</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">collectModules</span><span class="p">();</span>
<span class="c1">// build the final output</span>
<span class="nv">$out</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">foreach</span><span class="p">(</span><span class="nv">$collections</span> <span class="k">as</span> <span class="nv">$M_TYPE</span> <span class="o">=&gt;</span> <span class="nv">$collection</span><span class="p">){</span>
<span class="nv">$name</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getModuleValue</span><span class="p">(</span><span class="nv">$M_TYPE</span><span class="p">)</span> <span class="o">?:</span> <span class="nv">$this</span><span class="o">::</span><span class="na">LAYERNAMES</span><span class="p">[</span><span class="nv">$M_TYPE</span><span class="p">]);</span>
<span class="c1">// the section header</span>
<span class="nv">$out</span><span class="p">[]</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;%s (%012b)</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$name</span><span class="p">,</span> <span class="nv">$M_TYPE</span><span class="p">);</span>
<span class="c1">// the list of modules</span>
<span class="nv">$out</span><span class="p">[]</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">implode</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$collection</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nb">implode</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$out</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="run-the-custom-output">
<h2>Run the custom output<a class="headerlink" href="#run-the-custom-output" title="Link to this heading"></a></h2>
<p>To run the output we just need to set the <code class="docutils literal notranslate"><span class="pre">QROptions::$outputInterface</span></code> to our custom class:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span><span class="nv">$options</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">QROptions</span><span class="p">;</span>
<span class="nv">$options</span><span class="o">-&gt;</span><span class="na">outputInterface</span> <span class="o">=</span> <span class="nx">MyCustomOutput</span><span class="o">::</span><span class="na">class</span><span class="p">;</span>
<span class="nv">$options</span><span class="o">-&gt;</span><span class="na">connectPaths</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
<span class="nv">$options</span><span class="o">-&gt;</span><span class="na">drawLightModules</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
<span class="c1">// our custom module values</span>
<span class="nv">$options</span><span class="o">-&gt;</span><span class="na">moduleValues</span> <span class="o">=</span> <span class="p">[</span>
<span class="nx">QRMatrix</span><span class="o">::</span><span class="na">M_DATA</span> <span class="o">=&gt;</span> <span class="s1">&#39;these-modules-are-light&#39;</span><span class="p">,</span>
<span class="nx">QRMatrix</span><span class="o">::</span><span class="na">M_DATA_DARK</span> <span class="o">=&gt;</span> <span class="s1">&#39;here-is-a-dark-module&#39;</span><span class="p">,</span>
<span class="p">];</span>
<span class="nv">$qrcode</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">QRCode</span><span class="p">(</span><span class="nv">$options</span><span class="p">);</span>
<span class="nv">$qrcode</span><span class="o">-&gt;</span><span class="na">addByteSegment</span><span class="p">(</span><span class="s1">&#39;test&#39;</span><span class="p">);</span>
<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$qrcode</span><span class="o">-&gt;</span><span class="na">render</span><span class="p">());</span>
</pre></div>
</div>
<p>Alternatively, you can invoke the <code class="docutils literal notranslate"><span class="pre">QROutputInterface</span></code> manually:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span><span class="nv">$qrcode</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">QRCode</span><span class="p">(</span><span class="nv">$options</span><span class="p">);</span>
<span class="nv">$qrOutputInterface</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyCustomOutput</span><span class="p">(</span><span class="nv">$options</span><span class="p">,</span> <span class="nv">$qrcode</span><span class="o">-&gt;</span><span class="na">getMatrix</span><span class="p">(</span><span class="nv">$data</span><span class="p">));</span>
<span class="c1">//dump the output, which is equivalent to QRCode::render()</span>
<span class="nv">$qrOutputInterface</span><span class="o">-&gt;</span><span class="na">dump</span><span class="p">();</span>
<span class="c1">// render to file</span>
<span class="nv">$qrOutputInterface</span><span class="o">-&gt;</span><span class="na">dump</span><span class="p">(</span><span class="s1">&#39;/path/to/qrcode.svg&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>The output looks similar to the following:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>these-modules-are-light (000000000010)
x: 0, y: 0
x: 1, y: 0
x: 2, y: 0
...
here-is-a-dark-module (100000000010)
x: 4, y: 4
x: 5, y: 4
x: 6, y: 4
...
</pre></div>
</div>
<p>Profit!</p>
</section>
<section id="summary">
<h2>Summary<a class="headerlink" href="#summary" title="Link to this heading"></a></h2>
<p>Weve learned how to create a custom output class for a string based format similar to several of the built-in formats such as SVG or EPS.</p>
<p>The full code of our custom class below:</p>
<div class="highlight-php notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">MyCustomOutput</span> <span class="k">extends</span> <span class="nx">QROutputAbstract</span><span class="p">{</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">prepareModuleValue</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="k">return</span> <span class="nb">strtolower</span><span class="p">(</span><span class="nv">$value</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">getDefaultModuleValue</span><span class="p">(</span><span class="nx">bool</span> <span class="nv">$isDark</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="nf">moduleValueIsValid</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span><span class="o">:</span><span class="nx">bool</span><span class="p">{</span>
<span class="k">return</span> <span class="nb">is_string</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span> <span class="o">&amp;&amp;</span> <span class="nb">preg_match</span><span class="p">(</span><span class="s1">&#39;/^[a-z-]+$/i&#39;</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span> <span class="o">===</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">dump</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$file</span> <span class="o">=</span> <span class="k">null</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="nv">$collections</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">collectModules</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">module</span><span class="p">(</span><span class="o">...</span><span class="p">));</span>
<span class="c1">// build the final output</span>
<span class="nv">$out</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">foreach</span><span class="p">(</span><span class="nv">$collections</span> <span class="k">as</span> <span class="nv">$M_TYPE</span> <span class="o">=&gt;</span> <span class="nv">$collection</span><span class="p">){</span>
<span class="nv">$name</span> <span class="o">=</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getModuleValue</span><span class="p">(</span><span class="nv">$M_TYPE</span><span class="p">)</span> <span class="o">?:</span> <span class="nv">$this</span><span class="o">::</span><span class="na">LAYERNAMES</span><span class="p">[</span><span class="nv">$M_TYPE</span><span class="p">]);</span>
<span class="c1">// the section header</span>
<span class="nv">$out</span><span class="p">[]</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;%s (%012b)</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$name</span><span class="p">,</span> <span class="nv">$M_TYPE</span><span class="p">);</span>
<span class="c1">// the list of modules</span>
<span class="nv">$out</span><span class="p">[]</span> <span class="o">=</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s2">&quot;%s</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nb">implode</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$collection</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nb">implode</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$out</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">moduleTransform</span><span class="p">(</span><span class="nx">int</span> <span class="nv">$x</span><span class="p">,</span> <span class="nx">int</span> <span class="nv">$y</span><span class="p">,</span> <span class="nx">int</span> <span class="nv">$M_TYPE</span><span class="p">,</span> <span class="nx">int</span> <span class="nv">$M_TYPE_LAYER</span><span class="p">)</span><span class="o">:</span><span class="nx">string</span><span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">drawLightModules</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">matrix</span><span class="o">-&gt;</span><span class="na">isDark</span><span class="p">(</span><span class="nv">$M_TYPE</span><span class="p">)){</span>
<span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nb">sprintf</span><span class="p">(</span><span class="s1">&#39;x: %s, y: %s&#39;</span><span class="p">,</span> <span class="nv">$x</span><span class="p">,</span> <span class="nv">$y</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="QROutputAbstract.html" class="btn btn-neutral float-left" title="QROutputAbstract" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="../Built-In-Output/QREps.html" class="btn btn-neutral float-right" title="QREps" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2026, smiley.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>