JuliaImages / QRCoders.jl

Creating QR Codes within Julia
https://juliaimages.org/QRCoders.jl/
MIT License
67 stars 11 forks source link

Suggestion: unicode pixel output #25

Closed notinaboat closed 1 year ago

notinaboat commented 1 year ago

A little hack to show a QRCode on the terminal with two pixels per terminal row.

julia> pixel_char(x) = all(x) ? '█' : x[1] ? '▀' : x[2] ? '▄' : ' '
julia> qr_string(d) = join((String(pixel_char.(eachcol(d[i:i+1,:]))) for i in 1:2:d.dims[1]-1), "\n")
julia> qrcode("http://julialang.org") |> qr_string |> print

    █▀▀▀▀▀█ ▄ ▀▄ ▄█   █▀▀▀▀▀█    
    █ ███ █ █▀█▄█▄▀▄█ █ ███ █    
    █ ▀▀▀ █  █▄▄█▄▀ ▄ █ ▀▀▀ █    
    ▀▀▀▀▀▀▀ █ ▀▄▀ ▀▄█ ▀▀▀▀▀▀▀    
    ▀▄▄▄ ▄▀ █▀▀ █▀██ ▀▀▄▄███     
    ▄█▄▀▄ ▀▀ ▄▄▄▀▀██▄▀▄█ █ ▀█    
    █▄██▀▄▀█▀█▄▀▄█▀▄█ ▀▄   ▄▀    
    █ ▀█▀▄▀█▄▀  ▄██▀█▄▄ ▀▀▄▀█    
    ▀ ▀▀  ▀▀█ ▄ ▀ ▀▀█▀▀▀█ █      
    █▀▀▀▀▀█  ██▄▀▀█▄█ ▀ █▀  █    
    █ ███ █  ██▀▄▄ ▀███▀▀█▀██    
    █ ▀▀▀ █  ▀▄ ▄█▀ █ ▄█▄ ▀ █    
    ▀▀▀▀▀▀▀ ▀▀ ▀▀▀  ▀ ▀  ▀  ▀    
inokawazu commented 1 year ago

Looks nice, I can confirm it works as a QR Code! I would wonder it is possible to adjust the aspect ratio to approximate 1:1.

notinaboat commented 1 year ago

The aspect ratio depends mostly on the terminal font.

On my 7" Raspberry Pi touch screen using the default linux terminal font it looks pretty good...

IMG_6555

inokawazu commented 1 year ago

@notinaboat, sorry, yes this must be a GitHub issue with their fonts ig. I can confirm to get 1:1 on my Linux box's terminal. Looks good imo.

RexWzh commented 1 year ago

Great!! I like the idea. @notinaboat It looks nice in my device (Ubuntu). This can be added as part of the style plan.

ADD: I think it's about UnicodePlots as mentioned in #8


I just try some other Unicode, but had a worse behavior.

julia> join(Char.(0x25A0:0x25af), ' ')
"■ □ ▢ ▣ ▤ ▥ ▦ ▧ ▨ ▩ ▪ ▫ ▬ ▭ ▮ ▯"
pixelchar(x::Integer) = Char(0x25a0 + x)
pixelchar(line::AbstractVector) = join(pixelchar.(line), ' ')
qrstring(mat) = join(pixelchar.(eachrow(mat)), '\n')
qrstring(qrcode("Hello world!")) |> print

output:

□ □ □ □ □ □ □ ■ ■ ■ ■ □ ■ ■ □ □ □ □ □ □ □
□ ■ ■ ■ ■ ■ □ ■ □ ■ □ □ ■ ■ □ ■ ■ ■ ■ ■ □
□ ■ □ □ □ ■ □ ■ ■ □ □ □ ■ ■ □ ■ □ □ □ ■ □
□ ■ □ □ □ ■ □ ■ ■ ■ ■ □ □ ■ □ ■ □ □ □ ■ □
□ ■ □ □ □ ■ □ ■ □ □ ■ □ □ ■ □ ■ □ □ □ ■ □
□ ■ ■ ■ ■ ■ □ ■ ■ □ □ □ ■ ■ □ ■ ■ ■ ■ ■ □
□ □ □ □ □ □ □ ■ □ ■ □ ■ □ ■ □ □ □ □ □ □ □
■ ■ ■ ■ ■ ■ ■ ■ ■ □ □ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
□ ■ □ ■ □ ■ □ ■ ■ ■ ■ ■ □ ■ ■ ■ □ ■ ■ □ ■
□ □ □ □ □ □ ■ ■ ■ ■ ■ □ ■ ■ □ □ □ ■ ■ □ □
□ □ □ ■ ■ ■ □ ■ □ □ □ □ ■ □ ■ □ □ □ □ □ □
■ □ ■ ■ ■ □ ■ □ ■ □ □ □ □ ■ ■ ■ □ ■ ■ □ ■
■ □ ■ □ □ □ □ ■ ■ ■ ■ □ ■ □ ■ □ □ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ □ □ ■ □ ■ □ ■ ■ ■ ■ □ □ ■
□ □ □ □ □ □ □ ■ ■ ■ □ ■ □ ■ ■ □ □ ■ □ □ □
□ ■ ■ ■ ■ ■ □ ■ ■ □ □ ■ ■ ■ ■ □ ■ ■ ■ □ ■
□ ■ □ □ □ ■ □ ■ □ ■ □ ■ □ ■ ■ ■ □ ■ ■ □ ■
□ ■ □ □ □ ■ □ ■ ■ □ □ □ □ ■ □ □ □ ■ □ □ ■
□ ■ □ □ □ ■ □ ■ □ ■ □ ■ □ ■ □ ■ □ ■ □ ■ □
□ ■ ■ ■ ■ ■ □ ■ ■ □ ■ □ ■ ■ ■ ■ □ ■ ■ □ ■
□ □ □ □ □ □ □ ■ □ ■ ■ □ □ ■ ■ □ ■ ■ ■ □ □

It looks better when replacing 0x25A0 by 0x2b1c(■ □ by ⬛⬜)

pixelchar(x::Integer) = Char(0x2b1c - x)
pixelchar(line::AbstractVector) = join(pixelchar.(line))
qrstring(qrcode("Hello world!"; compact=false)) |> print

Looks well it my device(though the size is too large:rofl:) image

RexWzh commented 1 year ago

A little hack to show a QRCode on the terminal with two pixels per terminal row.

julia> pixel_char(x) = all(x) ? '█' : x[1] ? '▀' : x[2] ? '▄' : ' '
julia> qr_string(d) = join((String(pixel_char.(eachcol(d[i:i+1,:]))) for i in 1:2:d.dims[1]-1), "\n")
julia> qrcode("http://julialang.org") |> qr_string |> print

    █▀▀▀▀▀█ ▄ ▀▄ ▄█   █▀▀▀▀▀█    
    █ ███ █ █▀█▄█▄▀▄█ █ ███ █    
    █ ▀▀▀ █  █▄▄█▄▀ ▄ █ ▀▀▀ █    
    ▀▀▀▀▀▀▀ █ ▀▄▀ ▀▄█ ▀▀▀▀▀▀▀    
    ▀▄▄▄ ▄▀ █▀▀ █▀██ ▀▀▄▄███     
    ▄█▄▀▄ ▀▀ ▄▄▄▀▀██▄▀▄█ █ ▀█    
    █▄██▀▄▀█▀█▄▀▄█▀▄█ ▀▄   ▄▀    
    █ ▀█▀▄▀█▄▀  ▄██▀█▄▄ ▀▀▄▀█    
    ▀ ▀▀  ▀▀█ ▄ ▀ ▀▀█▀▀▀█ █      
    █▀▀▀▀▀█  ██▄▀▀█▄█ ▀ █▀  █    
    █ ███ █  ██▀▄▄ ▀███▀▀█▀██    
    █ ▀▀▀ █  ▀▄ ▄█▀ █ ▄█▄ ▀ █    
    ▀▀▀▀▀▀▀ ▀▀ ▀▀▀  ▀ ▀  ▀  ▀    

Thanks for the suggestion @notinaboat . It is now as an implementation in style.jl.