Skip to content

Commit

Permalink
Merge pull request #28 from RexWzh/master
Browse files Browse the repository at this point in the history
Add styles
  • Loading branch information
RexWzh authored Oct 5, 2022
2 parents 4dc72ae + 5aedf51 commit ba935ec
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 16 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
test/testimages/*.png
.vscode/
*.jl.cov
*.jl.*.cov
Expand Down
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
name = "QRCoders"
uuid = "f42e9828-16f3-11ed-2883-9126170b272d"
authors = ["Jérémie Gillet <[email protected]> and contributors"]
version = "1.0.1"
version = "1.1.0"

This comment has been minimized.

Copy link
@RexWzh

RexWzh Oct 5, 2022

Author Member

More styles for QRCoders.jl will be added in version 1.1.x.

@JuliaRegistrator register branch=master

This comment has been minimized.

Copy link
@RexWzh

RexWzh Oct 5, 2022

Author Member

@JuliaRegistrator register branch=master


[deps]
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
ImageCore = "a09fc81d-aa75-5fe9-8630-4744c3626534"
ImageIO = "82e4d734-157c-48bb-816b-45c225c6df19"
UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228"

[compat]
FileIO = "1"
ImageCore = "0.8, 0.9"
ImageIO = "0.4, 0.5, 0.6"
UnicodePlots = "2.12"
julia = "1.3"

[extras]
Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,35 @@ Keywords `eclevel`, `version`, `mode` and `mask`.

4. The mask pattern `mask` can be picked from 0 to 7. If the assigned `mask` is `nothing`, the mask pattern will picked by the penalty rules.

### Export a QR Code as a PNG file
### Unicode Plot
Method1, as mentioned in [issue#25](https://github.com/JuliaImages/QRCoders.jl/issues/25).
```jl
julia> unicodeplotbychar("Hello world!") |> print
█████████████████████████
██ ▄▄▄▄▄ █▀ █ ▄█ ▄▄▄▄▄ ██
██ █ █ █▄ █▀▄█ █ █ ██
██ █▄▄▄█ █ ██▀ █ █▄▄▄█ ██
██▄▄▄▄▄▄▄█ ▀ ▀ █▄▄▄▄▄▄▄██
██▄ ▀ ▀▀▄ ▀ ▄███ ▄▄█▄ ▀██
████▄ █ ▄▄ █▄▀▄▄███ ▄▀ ██
██████▄█▄▄▀ ▀▄█▄▀ █▀█▀██
██ ▄▄▄▄▄ █▄ ▀▀ █ ▀▄▄▄███
██ █ █ █▀▄▀ ██▄ ▄▀▀▀ ██
██ █▄▄▄█ █▀ █▄▀▀█▄█▄█▄██
██▄▄▄▄▄▄▄█▄█▄▄▄██▄█▄█▄███
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
```

Method2, Unicode plot by [UnicodePlots.jl](https://github.com/JuliaPlots/UnicodePlots.jl).

```julia
julia> unicodeplot("Hello world!")
```
![深度截图_选择区域_20221003234211](https://cdn.jsdelivr.net/gh/zhihongecnu/PicBed3/picgo/深度截图_选择区域_20221003234211.png)

Note: this only works in the REPL.

### Export a QR Code as a PNG/JPG file

Exporting files is also easy.

Expand Down
29 changes: 24 additions & 5 deletions src/QRCoders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,30 @@ Module that can create QR codes as data or images using `qrcode` or `exportqrcod
"""
module QRCoders

# create QR code
export qrcode, exportqrcode

# supported modes
export Mode, Numeric, Alphanumeric, Byte, Kanji, UTF8

# error correction levels
export ErrCorrLevel, Low, Medium, Quartile, High
export getmode, getversion, qrcode, exportqrcode

# get information about QR code
export getmode, getversion

# data type of Reed Solomon code
export Poly

# error type
export EncodeError

# QR code style
export unicodeplot, unicodeplotbychar

using ImageCore
using FileIO
using UnicodePlots

"""
Invalid step in encoding process.
Expand Down Expand Up @@ -89,14 +105,16 @@ include("tables.jl")
include("errorcorrection.jl")
include("matrix.jl")
include("encode.jl")
include("style.jl")

"""
qrcode(message::AbstractString;
eclevel = Medium(),
version = 0,
mode::Union{Nothing, Mode} = nothing,
mask::Union{Nothing, Int} = nothing,
compact = true)
compact::Bool = true,
width::Int = 4)
Create a `BitArray{2}` with the encoded `message`, with `true` (`1`) for the black
areas and `false` (`0`) as the white ones. If `compact` is `false`, white space
Expand All @@ -121,7 +139,8 @@ function qrcode( message::AbstractString
, version::Int = 0
, mode::Union{Nothing, Mode} = nothing
, mask::Union{Nothing, Int} = nothing
, compact::Bool = true)
, compact::Bool = true
, width::Int=4)
# Determining mode and version of the QR code
bestmode = getmode(message)
mode = !isnothing(mode) && bestmode mode ? mode : bestmode
Expand Down Expand Up @@ -152,8 +171,8 @@ function qrcode( message::AbstractString

# Format and version information
compact && return matrix
background = falses(size(matrix) .+ (8, 8))
background[5:end-4, 5:end-4] = matrix
background = falses(size(matrix) .+ (width*2, width*2))
background[width+1:end-width, width+1:end-width] = matrix
return background
end

Expand Down
60 changes: 60 additions & 0 deletions src/style.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# style of QR code
## support tables
## 1. Unicode plot

# 1. Unicode plot
"""
unicodeplot(mat::AbstractMatrix{Bool}; border=:none)
Uses UnicodePlots.jl to draw the matrix.
"""
function unicodeplot(mat::AbstractMatrix{Bool}; border=:none)
width, height = size(mat)
return heatmap(mat;
labels=false,
border=border,
colormap=:gray,
width=width,
height=height)
end

"""
unicodeplot(message::AbstractString
; border=:none)
Uses UnicodePlots.jl to draw the QR code of `message`.
"""
function unicodeplot(message::AbstractString; border=:none)
unicodeplot(qrcode(message;eclevel=Low(), compact=false, width=2); border=border)
end

## idea by @notinaboat
const pixelchars = [' ', '', '', '']
pixelchar(block::AbstractVector) = pixelchars[2 * block[1] + block[2] + 1]
pixelchar(bit::Bool) = pixelchars[1 + 2 * bit]

"""
unicodeplotbychar(mat::AbstractMatrix)
Plot of the QR code using Unicode characters.
Note that `true` represents white and `false` represents black.
"""
function unicodeplotbychar(mat::AbstractMatrix)
m = size(mat, 1)
txt = @views join((join(pixelchar.(eachcol(mat[i:i+1, :]))) for i in 1:2:m & 1 m), '\n')
isodd(m) || return txt
return @views txt * '\n' * join(pixelchar.(mat[m, :]))
end

"""
unicodeplotbychar(message::AbstractString)
Plot of the QR code using Unicode characters.
Note that `true` represents black and `false` represents white in qrcode,
which is the opposite of the image convention.
"""
function unicodeplotbychar(message::AbstractString)
unicodeplotbychar(.! qrcode(message; eclevel=Low(), compact=false, width=2))
end
16 changes: 11 additions & 5 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ using QRCoders:
getcharactercountindicator, charactercountlength,
padencodedmessage, encodedata, encodemessage,
# data convert
bitarray2int, int2bitarray, bits2bytes
bitarray2int, int2bitarray, bits2bytes,
# style
unicodeplot

using QRCoders.Polynomial:
# operator for GF(256) integers
Expand All @@ -33,15 +35,19 @@ randpoly(n::Int) = Poly([rand(0:255, n-1)..., rand(1:255)])
randpoly(range::AbstractVector{Int}) = randpoly(rand(range))
imgpath = "testimages/"
eclevels = [Low(), Medium(), Quartile(), High()]
modes = [Numeric(), Alphanumeric(), Byte(), Kanji()]

## operations
# operations
include("tst_operation.jl")

# format and version information
include("tst_fmtver.jl")

## encode message
# encode message
include("tst_encode.jl")

## original tests
include("tst_overall.jl")
# original tests
include("tst_overall.jl")

# style
include("tst_style.jl")
2 changes: 2 additions & 0 deletions test/testimages/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.jpg
*.png
Empty file removed test/testimages/.keep
Empty file.
3 changes: 0 additions & 3 deletions test/tst_encode.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
end

@testset "Capacity of the QRCode -- getversion " begin
modes = [Numeric(), Alphanumeric(), Byte(), Kanji()]
alphabets = [join('0':'9'), keys(alphanumeric), join(Char.(0:255)), keys(kanji)]
for (mode, alphabet) in zip(modes, alphabets)
tag = true
Expand Down Expand Up @@ -55,7 +54,6 @@ end

@testset "Indicator and pad codes" begin
## getcharactercountindicator, padencodedmessage
modes = [Numeric(), Alphanumeric(), Byte(), Kanji()]
alphabets = [join('0':'9'), vcat('0':'Z', collect(" \$%*+-./:")), join(Char.(0:255)), keys(kanji)]
v = rand(1:40)
i = (v 1) + (v 10) + (v 27)
Expand Down Expand Up @@ -250,7 +248,6 @@ end

# test case -- Random
alphabets = [join('0':'9'), keys(alphanumeric), join(Char.(0:255)), keys(kanji)]
modes = [Byte(), Alphanumeric(), UTF8(), Kanji()]
for (alphabet, mode) in zip(alphabets, modes), eclevel in eclevels
cap = last(characterscapacity[(eclevel, mode)])
msg = join(rand(alphabet, rand(1:cap)))
Expand Down
19 changes: 19 additions & 0 deletions test/tst_style.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Test for style of QR code
@testset "Unicode plot" begin
# by UnicodePlots
alphabets = [join('0':'9'), keys(alphanumeric), join(Char.(0:255)), keys(kanji)]
for alphabet in alphabets
msg = join(rand(alphabet, 100))
canvas = unicodeplot(msg)
end
@test true

# by Unicode characters
alphabets = [join('0':'9'), keys(alphanumeric), join(Char.(0:255)), keys(kanji)]
for alphabet in alphabets
msg = join(rand(alphabet, 100))
canvas = unicodeplotbychar(msg)
end
@test true
unicodeplotbychar("https://github.com/JuliaImages/QRCoders.jl") |> println
end

4 comments on commit ba935ec

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/69585

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.1.0 -m "<description of version>" ba935ec773c334736b775bb9a0c3653adf3c9df6
git push origin v1.1.0

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request updated: JuliaRegistries/General/69585

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.1.0 -m "<description of version>" ba935ec773c334736b775bb9a0c3653adf3c9df6
git push origin v1.1.0

@RexWzh
Copy link
Member Author

@RexWzh RexWzh commented on ba935ec Oct 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register branch=master

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request updated: JuliaRegistries/General/69585

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.1.0 -m "<description of version>" ba935ec773c334736b775bb9a0c3653adf3c9df6
git push origin v1.1.0

Please sign in to comment.