# \[ANN\] QRCode.jl: Create QR Code within Julia

**URL:** https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923
**Category:** Community
**Tags:** package, announcement
**Created:** [July 29, 2019, 3:46am UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923 "2019-07-29T03:46:20Z")
**Posts on this page:** 11
**Page:** 2

<div class="post-metadata">

### Author: ![dave.f.kleinschmidt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dave.f.kleinschmidt/32/55_2.png) [@dave.f.kleinschmidt](https://discourse.julialang.org/u/dave.f.kleinschmidt)
#### Post date: [July 29, 2019, 3:16pm UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/21 "2019-07-29T15:16:49Z")

</div>

Ha, I _also_ needed this a week ago (for an otherwise all-Julia poster…)

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [July 29, 2019, 3:17pm UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/22 "2019-07-29T15:17:03Z")

</div>

The advantage of returning something that will `show` as an image is that interfaces like IJulia or Juno, will know what to do automatically:

![34](https://global.discourse-cdn.com/julialang/original/3X/c/2/c2556ac91f6ae7896db17300006c241ef9e3b142.png)

---

<div class="post-metadata">

### Author: ![jiegillet](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jiegillet](https://discourse.julialang.org/u/jiegillet)
#### Post date: [July 30, 2019, 12:43am UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/23 "2019-07-30T00:43:04Z")

</div>

That actually is a very good point. Is there a way to define some sort of `show` function that would output an image without changing the structure? I guess I’d have to make it a `struct` then…

---

<div class="post-metadata">

### Author: ![Nosferican](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nosferican/32/9275_2.png) [@Nosferican](https://discourse.julialang.org/u/Nosferican)
#### Post date: [July 30, 2019, 1:27am UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/24 "2019-07-30T01:27:04Z")

</div>

Having those as `.eps` would also be great such that those can be used in LaTeX during a build process.

---

<div class="post-metadata">

### Author: ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)
#### Post date: [July 30, 2019, 4:41am UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/25 "2019-07-30T04:41:23Z")

</div>

That’s the idea - wrap it in a struct and override `Base.show`. Though there’s an attractive simplicity in just returning a `BitArray` 🙂

If you do want to go with a wrapper type you might use `QRCode` though you’d have to rename your package to QRCodes.jl (module name pluralization is an ecosystem convention to deal with this, eg `Colors.Color`, `Dates.Date`, `Rotations.Rotation` etc etc)

If you made a wrapper, what interface would you want it to conform to other than having a nice default `show` method? Eg, is it a graphical object, an `AbstractMatrix` or something else entirely? Perhaps best to keep it simple:

```julia
struct QRCode
    data::BitMatrix
    # Add more things here, eg the code version,
    # original source data string, etc
end

function Base.show(io::IO, code::QRCode)
    # You can include the original text in a header line too if it's part of QRCode
    # Minimal ANSI color text representation:
    for i=1:size(code.data,1)
        println(io, join([code.data[i,j] ? "\e[30m██" : "\e[97m██" for j=1:size(code.data,2)]))
    end
end

# possibly also `show(io::IO, ::MIME"text/html", qrc::QRCode)` for IJulia and the like?

```

---

<div class="post-metadata">

### Author: ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)
#### Post date: [July 30, 2019, 7:03am UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/26 "2019-07-30T07:03:23Z")

</div>

Looking at your API I think it would be useful to make the export list more minimal. Having a small export list means you introduce few concepts (types - nouns; functions - verbs) for users to learn about. A minimal set of exported names is also less likely to clash with other packages. Here’s some things to try:

- Avoid exporting really generic names like `getversion` if possible. The question to ask is: do I have a similarly generic _meaning_ to go with each generically named function I export? If not, either make the names more specific, resist exporting them, or find a generic function from a different package which has the correct semantics and extend that.
- It’s possible to model `ErrCorrLevel` with types like you’ve done but modelling it with values would be simpler. I’d be inclined to just pass symbol values `:low`, `:medium`, `:high` for the error correction levels, then you can remove those extra types. Similarly for `Mode` and its subtypes.
- With a type `QRCode` to model your data, you may get away with exporting only `QRCode` as the public API:
  - `qrcode` would become the constructor `QRCode`
  - `exportqrcode` might become `save(path, code::QRCode)`
  - `getversion` and `getmode` might be handled several ways depending on your intent:
    - renamed as exported functions `qrversion` and `qrmode`
    - accessible as public fields of `QRCode`
    - documented as public non-exported functions `QRCodes.version` and `QRCodes.mode`

 ![qr](https://global.discourse-cdn.com/julialang/original/3X/b/f/bf49063c6f447ec9a691a15cdbc58d0d25d03c75.png)

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [July 30, 2019, 12:48pm UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/27 "2019-07-30T12:48:41Z")

</div>

[https://github.com/rafaqz/UnicodeGraphics.jl](https://github.com/rafaqz/UnicodeGraphics.jl) can also convert arrays to braile and block chars. Pretty much the same thing but fast (for showing live simulations over ssh hahah)

---

<div class="post-metadata">

### Author: ![jiegillet](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jiegillet](https://discourse.julialang.org/u/jiegillet)
#### Post date: [July 30, 2019, 1:13pm UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/28 "2019-07-30T13:13:14Z")

</div>

Thank you very much for all the advice. It all looks like fun things to do with Julia, especially as a learning exercise. I think I’m leaning towards leaving it as simple as possible, add a few options for exporting graphics (png, eps, pdf, svg…) and let people go nuts if they want something more. But I’ll think about it more.

I’m surprised you tell me to export less things, I thought I was being minimalistic already ^^  
But thank you, I’ll consider your advice.

As for `ErrCorrLevel` and `Mode`, I love type programming too much to give them up (I’m a Haskell kind of guy). I really enjoyed combining multiple dispatch and types to define the different encoding functions.

Thanks again for your feedback!

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [July 30, 2019, 2:19pm UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/29 "2019-07-30T14:19:29Z")

</div>

The problem with the block chars approach (used by UnicodeGraphics and ImageInTerminal) is that the line spacing can introduce thin white lines through the image. Not much of a problem for plots, but it makes QR-codes unscannable. For example, on my (MacOS default) terminal it looks like this:  
 ![03](https://global.discourse-cdn.com/julialang/original/3X/c/f/cf56b4da2584edc845902970e3a12772d4e36686.png)

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [July 30, 2019, 4:04pm UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/30 "2019-07-30T16:04:56Z")

</div>

Yeah it will in atom. It doesnt in a lot of linux terminal fonts which is the real use case. Its probably not usefull for this problem, I was just pointing out there are easier ways than unicodeplots to print arrays and in the repl as people were suggesting that

---

<div class="post-metadata">

### Author: ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)
#### Post date: [July 31, 2019, 12:58pm UTC](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923/31 "2019-07-31T12:58:31Z")

</div>

> [@jiegillet](#):
>
> I really enjoyed combining multiple dispatch and types to define the different encoding functions

Great! Programming with multiple dispatch can be very satisfying. There are some circumstances where dispatching on types like this does make a lot sense (from an API standpoint). For example, if the user needs to be able to define their own type and expect the internals of the package to dispatch back to a user-defined function. I don’t know much about QR codes, but I guess they’re defined by a standard and not really extensible in this way. Another case would be when you’ve got tight code in an inner loop and you can’t afford the cost of dispatching on the value. Using types in that case could get a speedup because the compiler will generate type-specialized code for each “selector type”.

[Previous page](https://discourse.julialang.org/t/ann-qrcode-jl-create-qr-code-within-julia/26923.md?page=1)
