<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Julia Community 🟣: RexWang</title>
    <description>The latest articles on Julia Community 🟣 by RexWang (@rexwzh).</description>
    <link>https://forem.julialang.org/rexwzh</link>
    <image>
      <url>https://forem.julialang.org/images/Vcv3KIhI2AIk7HeDn5tzC0qHi2yl8850IyGSLCgCoyA/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L3VzZXIvcHJvZmls/ZV9pbWFnZS84NzQv/ODk5ODViZWItZDVj/ZC00ZjkwLWFiY2Yt/YTc0ZTQwMzA4ZDYy/LmpwZWc</url>
      <title>Julia Community 🟣: RexWang</title>
      <link>https://forem.julialang.org/rexwzh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.julialang.org/feed/rexwzh"/>
    <language>en</language>
    <item>
      <title>QRCoders.jl: Efficient generator for especial QR codes in Julia</title>
      <dc:creator>RexWang</dc:creator>
      <pubDate>Sat, 26 Nov 2022 13:48:41 +0000</pubDate>
      <link>https://forem.julialang.org/rexwzh/coder-decoder-for-qr-codes-ospp22-work-product-3gn4</link>
      <guid>https://forem.julialang.org/rexwzh/coder-decoder-for-qr-codes-ospp22-work-product-3gn4</guid>
      <description>&lt;p&gt;In this article, we will talk about two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does a QR code consist of, and what is the theory behind it?&lt;/li&gt;
&lt;li&gt;General usage of &lt;a href="https://github.com/JuliaImages/QRCoders.jl"&gt;QRCoders.jl&lt;/a&gt; and &lt;a href="https://github.com/JuliaImages/QRDecoders.jl"&gt;QRDecoders.jl&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These packages are created as main works of the OSPP'22 project. They are built following the ISO/IEC 18004:2015 standard, the excellent &lt;a href="https://www.thonky.com/qr-code-tutorial/"&gt;tutorial&lt;/a&gt; and the &lt;a href="https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders"&gt;wikiversity-entry&lt;/a&gt;. Therefore, images generated by QRCoders.jl can be decoded by a common QR code decoder or by QRDecoders.jl.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more information, please refer to the &lt;a href="https://discourse.julialang.org/t/ann-coder-and-decoder-of-qr-codes/88087"&gt;announcement&lt;/a&gt; in Julia Discourse.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Decomposition of QRCodes
&lt;/h2&gt;

&lt;p&gt;There are two parameters that are crucial to the capacity of a QR code: &lt;strong&gt;Version&lt;/strong&gt; and &lt;strong&gt;Error correction level&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The size of the QR code with &lt;strong&gt;version&lt;/strong&gt; &lt;code&gt;k(1-40)&lt;/code&gt; is &lt;code&gt;17+4k x 17+4k&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;QR codes have four error correction levels, &lt;code&gt;L&lt;/code&gt;, &lt;code&gt;M&lt;/code&gt;, &lt;code&gt;Q&lt;/code&gt;, &lt;code&gt;H&lt;/code&gt;. Higher the error correction level needs more error correction bits, thus the capacity of the QR code will be smaller.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following figure is a QR code with version 7, which is mainly divided into &lt;strong&gt;Function Patterns&lt;/strong&gt; and &lt;strong&gt;Encoding Region&lt;/strong&gt;.&lt;br&gt;
    &lt;a href="https://forem.julialang.org/images/jCHSY-n4WGwQ-YgeHYvTQLhQIub9JGrOH-ObeNehfDQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vdmVyc2lv/bjcucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/jCHSY-n4WGwQ-YgeHYvTQLhQIub9JGrOH-ObeNehfDQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vdmVyc2lv/bjcucG5n" alt="QRCode of version 7" width="880" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Function Patterns: used for image detection&lt;br&gt;
&lt;a href="https://forem.julialang.org/images/A2SBqUkWyeG3KNMCadyvRh5HbLkzgGVRVOYf903y3XQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vMjAyMjA2/MDIyMzAxNTAucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/A2SBqUkWyeG3KNMCadyvRh5HbLkzgGVRVOYf903y3XQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vMjAyMjA2/MDIyMzAxNTAucG5n" alt="Function Patterns" width="524" height="538"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encoding Region, including &lt;strong&gt;format information&lt;/strong&gt;, &lt;strong&gt;version information&lt;/strong&gt; and &lt;strong&gt;encoding data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Format information is consisted of &lt;strong&gt;error correction level&lt;/strong&gt; and &lt;strong&gt;mask pattern&lt;/strong&gt;, 15 bits in total
&lt;img src="https://forem.julialang.org/images/jnG4o8Z1D3pXpJ-QPJreXQ2yBbjuDj88OY5rxNlnDoc/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vMjAyMjA2/MDMyMTA5MzQucG5n" alt="Format" width="783" height="783"&gt;
&lt;/li&gt;
&lt;li&gt;Version information, only exists when version &lt;code&gt;≥7&lt;/code&gt;, 18 bits in total
&lt;img src="https://forem.julialang.org/images/9kbMwNJ24LHXhN1GrfmvFSOeth_L9OeGs6C2GAIsir4/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vMjAyMjA2/MDMwOTE2NDcucG5n" alt="Version" width="318" height="318"&gt;
&lt;/li&gt;
&lt;li&gt;Encoding data: the remaining empty space stores encoding data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Encoding process
&lt;/h3&gt;

&lt;p&gt;The encoding process of QRCodes is a bit complicated, but we can decompose it into several steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose the best encoding mode from the five modes: &lt;strong&gt;Numeric&lt;/strong&gt;, &lt;strong&gt;Alphanumeric&lt;/strong&gt;, &lt;strong&gt;Byte&lt;/strong&gt;, &lt;strong&gt;Kanji&lt;/strong&gt; and &lt;strong&gt;UTF8&lt;/strong&gt;, and then encode the data into bytes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Split the message bytes into several small blocks, each block is associated with an error correction block.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill in the Function Patterns and Encoding Region.&lt;br&gt;
&lt;a href="https://forem.julialang.org/images/-86Mov0_-J4VbzM_ivTT9Vq2wLs8vWiLa554oSmE5Ic/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vcXJpbWcu/Z2lm" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/-86Mov0_-J4VbzM_ivTT9Vq2wLs8vWiLa554oSmE5Ic/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vcXJpbWcu/Z2lm" alt="Construct a QR code " width="212" height="212"&gt;&lt;/a&gt;&lt;br&gt;
The Encoding Region is filled from right to left.&lt;br&gt;
&lt;a href="https://forem.julialang.org/images/ZecwPKIHjwDsE0ZHyaN0xiw0KFfF15Cx2THtT8Yra9w/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vcXJpbWdi/aXRzLmdpZg" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/ZecwPKIHjwDsE0ZHyaN0xiw0KFfF15Cx2THtT8Yra9w/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vcXJpbWdi/aXRzLmdpZg" alt="fill in data" width="212" height="212"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apply different masks to the QR matrix, and pick up the one with lowest penalty score. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mask patterns are used to make the QR code more scannable. As an example, the following case is designed to confuse the scanner.&lt;br&gt;
&lt;a href="https://forem.julialang.org/images/zpXJhkZpLamFFIBX0ia8TVa4L8gNNjIlMSOYMGiVGto/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vcXIyLnBu/Zw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/zpXJhkZpLamFFIBX0ia8TVa4L8gNNjIlMSOYMGiVGto/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vcXIyLnBu/Zw" alt="code-in-code" width="231" height="231"&gt;&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Decoding is the reverse process of encoding. The steps are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Locate the image&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Read the format area to get the mask pattern&lt;/li&gt;
&lt;li&gt;Apply the mask to restore the original QR matrix&lt;/li&gt;
&lt;li&gt;Extract the encoded data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error correction for the encoded data&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Decode the original string from the encoded data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most difficult parts are &lt;strong&gt;locating&lt;/strong&gt; and &lt;strong&gt;error-correction&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Theory behind error correction
&lt;/h2&gt;
&lt;h3&gt;
  
  
  An example
&lt;/h3&gt;

&lt;p&gt;During data transmission, some errors may occur, such as 1 is transmitted as 0 or some data is lost. Therefore, error correction code is introduced to improve the robustness of the data transmission.&lt;/p&gt;

&lt;p&gt;There are three applications of error correction codes: error detection, fill erased data and error correction.&lt;/p&gt;

&lt;p&gt;In essence, error correction codes introduce more space to represent a small data set. The redundant information improves the error tolerance of the data. We use an example to illustrate this process.&lt;/p&gt;

&lt;p&gt;Suppose Alice wants to send $x\in{0,1}$ to Bob, in order to increase the error tolerance, Alice uses the following encoding scheme&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
\begin{align*}&lt;br&gt;
x = 0 \quad &amp;amp;\rightarrow &amp;amp;\quad y=000 \&lt;br&gt;
x = 1 \quad &amp;amp;\rightarrow &amp;amp;\quad y=111&lt;br&gt;
\end{align*}&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;Now Alice sends the encoded $y$ to Bob&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error correction: suppose at most 1 bit error occurs during transmission, such as $000\rightarrow 010$, obviously Bob can decode $010$ as $0$, thus correct the error&lt;/li&gt;
&lt;li&gt;Error detection: suppose at most 2 bit errors occur during transmission, such as $000\rightarrow 110$, although Bob cannot determine whether the original information is $0$ or $1$, he can determine whether an error occurs during transmission&lt;/li&gt;
&lt;li&gt;fill erased data: suppose 2 bits are lost during transmission, such as $000\rightarrow 0**$, obviously Bob can fill in the missing data to get $000$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Coding Theory
&lt;/h3&gt;

&lt;p&gt;The example above uses a linear code with Hamming distance 3. In general, let $C$ be a linear code with Hamming distance $d$, then&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$C$ can detect at most $e\leq d-1$ errors&lt;/li&gt;
&lt;li&gt;$C$ can fill at most $e\leq d-1$ erased data&lt;/li&gt;
&lt;li&gt;$C$ can correct at most $e\leq \lfloor\frac{d-1}{2}\rfloor$ errors, i.e. $2e\leq d-1$&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Hamming distance is the minimum number of bits that need to be changed to convert one code to another, for example, the Hamming distance between $000$ and $010$ is 1, and the Hamming distance between $000$ and $110$ is 2.&lt;/p&gt;

&lt;p&gt;Let's understand this theorem through an image. The original information is a set of dots, and we use larger spheres to represent these dots. The Hamming distance of a code is the minimum distance between dots. When the number of errors is within half of the distance, we can always correct them.&lt;br&gt;
&lt;a href="https://forem.julialang.org/images/NPEJD4dwJE-gtAix-4d-lvq8Rf4i0MRnVPbgXYuJbJk/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDIv/cGljZ28vMjAyMjA1/MDQxMTU3MTMucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/NPEJD4dwJE-gtAix-4d-lvq8Rf4i0MRnVPbgXYuJbJk/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDIv/cGljZ28vMjAyMjA1/MDQxMTU3MTMucG5n" alt="Hamming ball" width="677" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ReedSolomon is one of the most commonly used error correction codes. Moreover, it meets the following criterias:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stronger error handling ability&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smaller redundant information as possible&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Efficient encoding and decoding algorithms&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  General usage
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a QR code&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;QRCoders&lt;/span&gt;
&lt;span class="c"&gt;# creat a QRCode object&lt;/span&gt;
&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QRCode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# use the object to creat a QR code&lt;/span&gt;
&lt;span class="n"&gt;qrcode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# equivalently, use the function directly&lt;/span&gt;
&lt;span class="n"&gt;qrcode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello world!"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;a href="https://forem.julialang.org/images/OzT6CLCK2dudaGYADBeeC006j9ZLkEnqMK8_9p9eGKo/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3ly/eW45N3Y0b3k5ZGlz/djExeTZiLnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/OzT6CLCK2dudaGYADBeeC006j9ZLkEnqMK8_9p9eGKo/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL3ly/eW45N3Y0b3k5ZGlz/djExeTZiLnBuZw" alt="QRCode-in-REPL" width="549" height="482"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Export pictures from QR codes&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="c"&gt;# direct method&lt;/span&gt;
&lt;span class="n"&gt;exportqrcode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello world!"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hello.png"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# use the object `QRCode`&lt;/span&gt;
&lt;span class="n"&gt;exportqrcode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Export animated GIF from QR codes&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;exportqrcode&lt;/span&gt;&lt;span class="x"&gt;([&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Julia"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"!"&lt;/span&gt;&lt;span class="x"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"hello.gif"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;&lt;a href="https://forem.julialang.org/images/lw8LaLEblF-Ybgx-vF7KMjXgUbxoZnWOz5iuzUFCnyo/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vaGVsbG8u/Z2lm" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/lw8LaLEblF-Ybgx-vF7KMjXgUbxoZnWOz5iuzUFCnyo/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vaGVsbG8u/Z2lm" alt="Hello Julia!" width="174" height="174"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Specified parameters&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QRCode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;eclevel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="x"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="x"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Decode message&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;QRDecoders&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;QRCoders&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Test&lt;/span&gt;
&lt;span class="c"&gt;# decode message from QR code matrix&lt;/span&gt;
&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QRCode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;mat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qrcode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qrdecode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mat&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@test&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Hello World!"&lt;/span&gt;
&lt;span class="nd"&gt;@test&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;

&lt;span class="c"&gt;# decode message from pictures&lt;/span&gt;
&lt;span class="n"&gt;exportqrcode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"test.png"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qrdecode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test.png"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@test&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Hello World!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Special QR codes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Unicode plot&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;QRCoders&lt;/span&gt;
&lt;span class="n"&gt;unicodeplot&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt; &lt;span class="c"&gt;# via UnicodePlots.jl&lt;/span&gt;
&lt;span class="c"&gt;# plot using Unicode characters `['█', '▀', '▄', ' ']`&lt;/span&gt;
&lt;span class="n"&gt;unicodeplotbychar&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;println&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This idea is suggested by &lt;a href="https://github.com/notinaboat"&gt;notinaboat&lt;/a&gt; in the &lt;a href="https://github.com/JuliaImages/QRCoders.jl/issues/25"&gt;issue#25&lt;/a&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;pixel drawing: Plot image in a QR code&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight julia"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="n"&gt;TestImages&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ImageTransformations&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileIO&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ColorTypes&lt;/span&gt;
&lt;span class="c"&gt;# read image&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;testimage&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cameraman"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QRCode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"HELLO WORLD"&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;inlen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qrwidth&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="n"&gt;bitimg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.!&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Bool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Gray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imresize&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inlen&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inlen&lt;/span&gt;&lt;span class="x"&gt;))))))&lt;/span&gt;
&lt;span class="c"&gt;# draw image inside the QR code&lt;/span&gt;
&lt;span class="n"&gt;mat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imageinqrcode&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bitimg&lt;/span&gt;&lt;span class="x"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;# file export&lt;/span&gt;
&lt;span class="n"&gt;mat&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;exportbitmat&lt;/span&gt;&lt;span class="x"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cameraman.png"&lt;/span&gt;&lt;span class="x"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;a href="https://forem.julialang.org/images/LXckrS-kt8TSRREXU2Y1MPRnfuylibPDAn0eY2dOIb8/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL215/ejBpa2RzdWE3eDcz/Zjdlc2l4LnBuZw" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/LXckrS-kt8TSRREXU2Y1MPRnfuylibPDAn0eY2dOIb8/w:880/mb:500000/ar:1/aHR0cHM6Ly9mb3Jl/bS5qdWxpYWxhbmcu/b3JnL3JlbW90ZWlt/YWdlcy91cGxvYWRz/L2FydGljbGVzL215/ejBpa2RzdWE3eDcz/Zjdlc2l4LnBuZw" alt="Image in QR code" width="178" height="178"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that this is not a simple padded image, but is plotted using error correction and free bits. &lt;strong&gt;So it is scannable by a normal QR code reader.&lt;/strong&gt; The idea of &lt;strong&gt;plot using free bits and error correction&lt;/strong&gt; is inspired by &lt;a href="https://github.com/ibukisaar"&gt;ibukisaar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Other styles are on the way, welcome to contribute!&lt;br&gt;
&lt;a href="https://forem.julialang.org/images/UJO1FEL2sXAa622s-cQq1rmB_50b3gCXXHBfYCUN8CQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vMjAyMjEx/MjgxMDE2NDcucG5n" class="article-body-image-wrapper"&gt;&lt;img src="https://forem.julialang.org/images/UJO1FEL2sXAa622s-cQq1rmB_50b3gCXXHBfYCUN8CQ/w:880/mb:500000/ar:1/aHR0cHM6Ly9jZG4u/anNkZWxpdnIubmV0/L2doL3poaWhvbmdl/Y251L1BpY0JlZDMv/cGljZ28vMjAyMjEx/MjgxMDE2NDcucG5n" alt="20221128101647" width="880" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;Styles of a QR code has a creative room that beyond one’s imaginations.&lt;/p&gt;

&lt;p&gt;However, due to my limited time and energy, I am currently focusing on the implementation of &lt;strong&gt;pixel drawing&lt;/strong&gt; only. Feel free to give your valuable suggestions to help improve this package!&lt;/p&gt;

</description>
      <category>juliaimages</category>
      <category>qrcoders</category>
      <category>qrdecoders</category>
    </item>
  </channel>
</rss>
