Liberty BASIC Community Forum
Special Topics and Projects >> Open Source Projects >> QR Codes
http://libertybasic.conforums.com/index.cgi?board=open&action=display&num=1321177792

QR Codes
Post by CryptoMan on Nov 13th, 2011, 03:49am

Can somebody generate QR Codes with LB ?

http://en.wikipedia.org/wiki/QR_code
Re: QR Codes
Post by stefanhes on Nov 13th, 2011, 06:09am

Everyone who can draw a filled square on the screen can.
QR-code = a lot of squares. After that use


#gb "print"
dump



Re: QR Codes
Post by tenochtitlanuk on Nov 13th, 2011, 08:41am

A neat way is to ask Google to do it for you- the following code is derived from Alyce's examples of scraping web content. Change the destination of the saved file if it gives grief in W7- I nearly always use ramdisk R:\ for such files..
I can't vouch for the result tho.!
Change the text you want- I used my web moniker of 'tenochtitlanuk'.
User Image
Code:
'Download an image from given URL to file on disk.

'LB NL 141?? & Alyce's Restaurant

http$ ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=tenochtitlanuk&chld=H|0"

nomainwin

result = DownloadToFile( http$, "QR.png")
timer 2000, [on]
wait
[on]
timer 0
if result <> 0 then
    print "Error downloading image."
else
    run "mspaint.exe " + chr$(34) +"QR.png" + chr$(34)
    print "Done"
end if

end

Function DownloadToFile( urlfile$, localfile$)
    open "URLmon" for dll as #url
    calldll #url, "URLDownloadToFileA",_
    0 as long,_         'null
    urlfile$ as ptr,_   'url to download
    localfile$ as ptr,_ 'save file name
    0 as long,_         'reserved, must be 0
    0 as long,_         'callback address, can be 0
    DownloadToFile as ulong  '0=success
    close #url
end function

 

Re: QR Codes
Post by tenochtitlanuk on Nov 17th, 2011, 4:47pm

Further comment- there are also on-line services to decode QR codes in a similar way- or you can download free exes that will run on your machine.
Re: QR Codes
Post by CS on Nov 19th, 2011, 12:23pm

Hello,

I use this site for my QR code needs.

http://www.qrstuff.com/

Not sure exactly on the conventions for the codes.
Re: QR Codes
Post by jaba on Nov 19th, 2011, 4:17pm

I had never even heard of QR codes until I read this post. Now, everywhere I go I see them. Interesting...
Re: QR Codes
Post by CryptoMan on Nov 23rd, 2011, 3:08pm

Thanks for all the replies.

I know all of those Internet based services.

I would like to know if anybody implemented this in pure Liberty Basic by obtaining the ISO standard for QR codes and implement the algorithm of how to draw all of the squares as described in the standard.

Probably there is some C or C++ open source which can be converted into Liberty Basic. The standard is quite complicated. I like to try it one day if I can find some time.

If anyone wants to see the standard and give it try can send me a message with his/her email.

I think it is a good intellectual challenge. I tend to believe anything is possible with LB.
Re: QR Codes
Post by Rod on Nov 24th, 2011, 01:39am

I had a look but hesitated because there seems to be such a variety of styles and encryption methods.

If there is one particular standard that you think would be right for Liberty why not publish the link.
Re: QR Codes
Post by CryptoMan on Nov 24th, 2011, 11:54am

INTERNATIONAL STANDARD ISO/IEC 18004

Information technology Automatic identification and data capture techniques QR Code 2005 bar code symbology specification



ISO/IEC
18004
Reference number
ISO/IEC 18004:2006(E)

Second edition
2006-09-01
Re: QR Codes
Post by marklew1956 on Aug 25th, 2016, 09:10am

Using the example above, how hard would it be to save the PNG file to disk? I'm not a power user and it seems that I each project I tackle has a few new challenges I have to overcome... this time it's the opening a url and saving the resulting png graphic to disk!
Re: QR Codes
Post by tenochtitlanuk on Aug 25th, 2016, 12:58pm

Easy! The original code saved it anyway! ( Look in the directory where you saved the LB code.) I've changed the code to make it more obvious where your code goes, and removed the line that opened it in Paint. Works OK for me under Linux...
Code:
'Download an image from given URL to file on disk.

'LB NL 141?? & Alyce's Restaurant

toEncode$ ="marklew1956"

http$ ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=" +toEncode$ +"&chld=H|0"

nomainwin

result = DownloadToFile( http$, "QR.png")
timer 2000, [on]
wait
[on]
timer 0
if result <> 0 then
    print "Error downloading image."
else
    print "Done, Saved as "; "QR.png"
end if

end

Function DownloadToFile( urlfile$, localfile$)
    open "URLmon" for dll as #url
    calldll #url, "URLDownloadToFileA",_
    0 as long,_         'null
    urlfile$ as ptr,_   'url to download
    localfile$ as ptr,_ 'save file name
    0 as long,_         'reserved, must be 0
    0 as long,_         'callback address, can be 0
    DownloadToFile as ulong  '0=success
    close #url
end function
 

Re: QR Codes
Post by marklew1956 on Aug 27th, 2016, 1:07pm

Thanks for the help! What I'm actually trying to do is get a text line and the qrcode on the same graphic window. What will be the simplest way to open the saved image and place it on a graphic window?
Re: QR Codes
Post by tenochtitlanuk on Aug 27th, 2016, 4:20pm

LB uses bmp image files. So it can't display a png directly. BUT...
To display a png you have several LB options- and I don't know how much experience you have.
One way is GDIplus. See GDIplus article
My way of choice on Linux ( or in the past MS Windows machines) is to install the free ImageMagick, which adds commands accessible from LB to size, load and alter in every conceivable way any image of any format. You'll find some examples on my website.
EDIT
ImageMagick

If this takes you out of your comfort zone I can try to create an example.
Re: QR Codes
Post by tenochtitlanuk on Aug 28th, 2016, 4:31pm

Here's an example using the GDI+ code from LB encyclopedia. You'll need to change the font name if you you don't use LB under Linux/Wine.
User Image
Code:
    nomainwin

    WindowWidth  = 400
    WindowHeight = 500

    graphicbox #main.g,  50,  50, 302, 352

    open "Picture load" for window_nf as #main

    #main.g "down; fill 30 30 80; color red; backcolor 30 30 80  ; flush"
    #main.g "font Ubuntu 24"

    #main   "trapclose [quit.main]"

    open "gdiplus.dll" for dll as #gdip

    toEncode$   ="marklew1956"
    http$       ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=" +toEncode$ +"&chld=H|0"
    result      = DownloadToFile( http$, "QR.png")

    timer 2000, [on0]
    wait
  [on0]
    timer 0

    if result <> 0 then print "Error downloading image.": end

    file$ ="QR.png"

    hBmp    =LoadImgFromFile( file$)
    if hBmp <>0 then
        loadbmp "pic", hBmp
        #main.g     "drawbmp pic 0 0; flush"
        unloadbmp "pic"    'Because LB doesnt delete it for us
        calldll #gdi32, "DeleteObject", hBmp as ulong, ret as ulong
        #main.g     "up; goto 60 340; down"
        #main.g     "\"; toEncode$
    else
        notice "Could not load the image file!"
    end if


    wait


[quit.main]
    close #gdip
    close #main
    end

function wchar$( string$)
    for i = 1 to len( string$)
        wchar$  =wchar$ +mid$( string$, i, 1) +chr$( 0)
    next i

    wchar$  =wchar$ +chr$( 0) +chr$( 0)
end function

function LoadImgFromFile( file$)
    struct dword, a as ulong
    gdistart$   =chr$( 1)

    for i = 1 to 15
        gdistart$   =gdistart$ +chr$( 0)
    next i

    calldll #gdip, "GdiplusStartup", dword as struct, gdistart$ as ptr, status as ulong

    token   =dword.a.struct

    if status <>0 then
        LoadImgFromFile   =0
    else
        wFileLoc$   =wchar$(file$)
        calldll #gdip, "GdipCreateBitmapFromFile", _
        wFileLoc$ as ptr, dword as struct, status as ulong
        hPic        =dword.a.struct

        if status <>0 then
            LoadImgFromFile =0
        else
            calldll #gdip, "GdipCreateHBITMAPFromBitmap", _
            hPic as ulong, dword as struct, 0 as ulong, status as ulong
            hBmp    =dword.a.struct

            if status <>0 then
                LoadImgFromFile =0
            else
                LoadImgFromFile =hBmp
            end if

            calldll #gdip, "GdipDisposeImage", hPic as ulong, ret as ulong
        end if

        calldll #gdip, "GdiplusShutdown", token as ulong, ret as ulong
    end if
end function

Function DownloadToFile( urlfile$, localfile$)
    open "URLmon" for dll as #url
    calldll #url, "URLDownloadToFileA",_
    0 as long,_         'null
    urlfile$ as ptr,_   'url to download
    localfile$ as ptr,_ 'save file name
    0 as long,_         'reserved, must be 0
    0 as long,_         'callback address, can be 0
    DownloadToFile as ulong  '0=success
    close #url
end function
 


When I tried the ( should be easier) calling of ImageMagick it failed on my Linux machine and I don't have a MS Windows machine here to try it.
Does anyone see why
Code:
    IM$         ="identify " +chr$( 34) +"/media/john/Stick2G/QR.png" +chr$( 34) +" > " +chr$( 34) +"/media/john/Stick2G/identify.txt" +chr$( 34)
    '   NB  identify "/media/john/Stick2G/QR.png" > "/media/john/Stick2G/identify.txt" works from terminal....
    run "cmd.exe /C "; chr$( 34); IM$; chr$( 34), HIDE
 

The command works from the Terminal, and other commands like
Code:
"dir > dir.txt" 
work happily...
It's been some time since I used the LB/ImageMagick combination.
Re: QR Codes
Post by CryptoMan on Aug 29th, 2016, 09:18am

All of these are palliative solutions. What I meant when I originally asked was a source code which will generate QR code from first principles in offline mode by implementing the required algorithm and using LB graphics primitives.


Re: QR Codes
Post by Rod on Aug 29th, 2016, 09:45am

I agree, we have managed barcodes in the past. I will try and spend some time on it.

When I looked the last time the encryption choices seemed daunting but it should be possible to get a single format QR code drawn.
Re: QR Codes
Post by tenochtitlanuk on Aug 29th, 2016, 4:36pm

My reply was to a new poster coming new to a five year old thread, not to your original post!

It's obviously POSSIBLE to create QR codes of one or more type from their definition. I'd question WHY to do this. It comes down to the answer of the mountaineer to 'Why do you climb mountains?' which was 'Because they are there.'
When I have 'spare time' I've been known to rise to such challenges. But the practical side of my brain says 'Change to Python. Import the relevant library and import the needed functionality'.

I'd be more interested in creating a new type of code, not bar or QR, and then attempting to implement it, with the necessary error correction. And writing a decoder which implements a pattern recognition, orientates it and decodes reliably. A major effort and no chance of it taking off commercially. But addictive fun, like crosswords....!
And then, I seem to remember making an 8-photocell reader and creating my own paper-tape code/decode software on an 1802 processer in about 1978... Plus ca change.
Re: QR Codes
Post by marklew1956 on Aug 30th, 2016, 4:18pm

Thanks for the help with the QR code software. I've gotten myself in a bit of a deadline and haven't had sufficient time to research and write the code myself. Now, another question. From the last example, how can I get the resulting window so I can actually print it? That's my ultimate use is to enter information from a tsv database file and have a program generate the barcodes, add the corresponding name and print out the results on a 5 x 8 inch card!
Re: QR Codes
Post by Rod on Aug 31st, 2016, 03:50am

To print the drawing you simply issue the graphicbox print [size] command

When you wish to print draw everything to the graphicbox, the QR image and the text, then issue a single flush command. Then print with #main.g "print 300"

The size parameter will determine how big your image is on the printed page. The graphicbox is 300 so print 300 will spread the whole image across the printed page.Experiment with the size parameter on your card stock and printer.
Re: QR Codes
Post by Rod on Aug 31st, 2016, 04:38am

Back to creating QR codes. Having looked again the range of options is daunting. I don't think it would be practical to build a complete encoding solution that met all standards.

It might be possible to pick out one format and produce a 64 character QR code that can be read by any scanner but is that useful?

If it is an inhouse solution a bar code is simpler. If it is a web address solution then what format (data) is going to be useful?


http://www.thonky.com/qr-code-tutorial/introduction
Re: QR Codes
Post by tenochtitlanuk on Aug 31st, 2016, 3:32pm

The following code prints two images of the selected QR code on a sheet. Easily modified to print a grid of different ones, or positioned to suit label-paper.

NB 1 The scaling is not intuitive.
NB 2 The bounding box for the printed area is made visible. ( my choice)
I wasted a lot of ink getting pages that were black everywhere but the QR part. In such cases it helps to print to pdf until you sort it out! Since I work under Linux I always wonder if it is a Wine bug.... There's definitely something funny. If I use 'print 16000' instead of 'print 8000' the bounding box scales but not the QR codes, whose size I can't change!! I don't have time at present to investigate what's going on. But as it stands you do get your printout.

LB does not give you a printer-select, so you have to make the chosen printer the default.
Code:
    nomainwin

    WindowWidth  = 471
    WindowHeight = 407

    graphicbox #main.g,  5,  6, 456, 366

    open "QR print" for window_nf as #main

'In an LB quirk, you need to be sure there's a bounding box defining possible graphic area
#main.g, "down ; color black ; place 0 0 ; box 8000 7000"

    #main.g "flush"
    #main.g "font Ubuntu 24"

    #main   "trapclose [quit.main]"

    open "gdiplus.dll" for dll as #gdip

    toEncode$   ="marklew1956"
    http$       ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=" +toEncode$ +"&chld=H|0"
    result      = DownloadToFile( http$, "QR.png")

    timer 2000, [on0]
    wait
  [on0]
    timer 0

    if result <> 0 then print "Error downloading image.": end

    file$ ="QR.png"

    hBmp    =LoadImgFromFile( file$)
    if hBmp <>0 then
        loadbmp "pic", hBmp
        #main.g     "drawbmp pic  52 52"
        #main.g     "drawbmp pic 372 52"
        unloadbmp "pic"
        calldll #gdi32, "DeleteObject", hBmp as ulong, ret as ulong

        #main.g     "flush ; print 8000"
' The size argument takes the pixels you have drawn and spreads them across the full printed width.
' Our image is 356 pixels wide- but 8000 pixels would be needed to fill the width of the printed page.
    else
        notice "Could not load the image file!"
    end if

    wait


[quit.main]
    close #gdip
    close #main
    end

function wchar$( string$)
    for i = 1 to len( string$)
        wchar$  =wchar$ +mid$( string$, i, 1) +chr$( 0)
    next i

    wchar$  =wchar$ +chr$( 0) +chr$( 0)
end function

function LoadImgFromFile( file$)
    struct dword, a as ulong
    gdistart$   =chr$( 1)

    for i = 1 to 15
        gdistart$   =gdistart$ +chr$( 0)
    next i

    calldll #gdip, "GdiplusStartup", dword as struct, gdistart$ as ptr, status as ulong

    token   =dword.a.struct

    if status <>0 then
        LoadImgFromFile   =0
    else
        wFileLoc$   =wchar$(file$)
        calldll #gdip, "GdipCreateBitmapFromFile", _
        wFileLoc$ as ptr, dword as struct, status as ulong
        hPic        =dword.a.struct

        if status <>0 then
            LoadImgFromFile =0
        else
            calldll #gdip, "GdipCreateHBITMAPFromBitmap", _
            hPic as ulong, dword as struct, 0 as ulong, status as ulong
            hBmp    =dword.a.struct

            if status <>0 then
                LoadImgFromFile =0
            else
                LoadImgFromFile =hBmp
            end if

            calldll #gdip, "GdipDisposeImage", hPic as ulong, ret as ulong
        end if

        calldll #gdip, "GdiplusShutdown", token as ulong, ret as ulong
    end if
end function

Function DownloadToFile( urlfile$, localfile$)
    open "URLmon" for dll as #url
    calldll #url, "URLDownloadToFileA",_
    0 as long,_         'null
    urlfile$ as ptr,_   'url to download
    localfile$ as ptr,_ 'save file name
    0 as long,_         'reserved, must be 0
    0 as long,_         'callback address, can be 0
    DownloadToFile as ulong  '0=success
    close #url
end function
 

Re: QR Codes
Post by Rod on Sep 1st, 2016, 06:48am

I changed John's example a little. I put in a down command, I did away with the large box which is only necessary if you are using scroll bars to see the image.

I changed the graphicbox size to 800x500 and then used size 800 as the printing parameter. This spreads the whole graphicbox across the width of the printed page.

It produces quite a large QR code, you can make it look a lot smaller by increasing both the size of the graphicbox and the printing size parameter. An 8000x5000 graphicbox and a print size parameter of 8000 would make the QR code one tenth of its current size. Play you can't break it.

Code:
    nomainwin

    WindowWidth  = 900
    WindowHeight = 600

    graphicbox #main.g,  10,  10, 800, 500

    open "QR print" for window_nf as #main

    #main.g "down"
    #main   "trapclose [quit.main]"

    open "gdiplus.dll" for dll as #gdip

    toEncode$   ="marklew1956"
    http$       ="http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=" +toEncode$ +"&chld=H|0"
    result      = DownloadToFile( http$, "QR.png")

    timer 2000, [on0]
    wait
  [on0]
    timer 0

    if result <> 0 then print "Error downloading image.": end

    file$ ="QR.png"

    hBmp    =LoadImgFromFile( file$)
    if hBmp <>0 then
        loadbmp "pic", hBmp
        #main.g     "drawbmp pic  222 72" '222,72 = 356 pixel image in middle of 800x500 graphicbox

        unloadbmp "pic"
        calldll #gdi32, "DeleteObject", hBmp as ulong, ret as ulong

        #main.g     "flush ; print 800"
    ' The size argument takes the pixels you have drawn and spreads them across the full printed width.
    ' Our image is 356 pixels wide the graphicbox is 800 pixels wide so to spread the graphicbox
    ' across the width of the printed page requires a size of 800.
    ' If you have your printer set to use 8x5 cards then the graphicbox image will fill the card
    ' and the QR code in my example will be in the middle of the card quite large.
    ' You can adjust the size of the printed QR code by changing the size parameter. If you make
    ' the size parameter bigger and the graphicbox bigger the QR code will shrink in size on the printed page.
    ' So a size of 8000 and a graphicbox 8000 wide will make the QR code much smaller and you can place it
    ' anywhere in the graphicbox
    else
        notice "Could not load the image file!"
    end if

    wait


[quit.main]
    close #gdip
    close #main
    end

function wchar$( string$)
    for i = 1 to len( string$)
        wchar$  =wchar$ +mid$( string$, i, 1) +chr$( 0)
    next i

    wchar$  =wchar$ +chr$( 0) +chr$( 0)
end function

function LoadImgFromFile( file$)
    struct dword, a as ulong
    gdistart$   =chr$( 1)

    for i = 1 to 15
        gdistart$   =gdistart$ +chr$( 0)
    next i

    calldll #gdip, "GdiplusStartup", dword as struct, gdistart$ as ptr, status as ulong

    token   =dword.a.struct

    if status <>0 then
        LoadImgFromFile   =0
    else
        wFileLoc$   =wchar$(file$)
        calldll #gdip, "GdipCreateBitmapFromFile", _
        wFileLoc$ as ptr, dword as struct, status as ulong
        hPic        =dword.a.struct

        if status <>0 then
            LoadImgFromFile =0
        else
            calldll #gdip, "GdipCreateHBITMAPFromBitmap", _
            hPic as ulong, dword as struct, 0 as ulong, status as ulong
            hBmp    =dword.a.struct

            if status <>0 then
                LoadImgFromFile =0
            else
                LoadImgFromFile =hBmp
            end if

            calldll #gdip, "GdipDisposeImage", hPic as ulong, ret as ulong
        end if

        calldll #gdip, "GdiplusShutdown", token as ulong, ret as ulong
    end if
end function

Function DownloadToFile( urlfile$, localfile$)
    open "URLmon" for dll as #url
    calldll #url, "URLDownloadToFileA",_
    0 as long,_         'null
    urlfile$ as ptr,_   'url to download
    localfile$ as ptr,_ 'save file name
    0 as long,_         'reserved, must be 0
    0 as long,_         'callback address, can be 0
    DownloadToFile as ulong  '0=success
    close #url
end function


 

Re: QR Codes
Post by tenochtitlanuk on Sep 1st, 2016, 07:55am

...and just to point out that you can download at smaller size in the first place, eg
Code:
http$       ="http://chart.apis.google.com/chart?cht=qr&chs=100x100&chl=" +toEncode$ +"&chld=H|0" 

Re: QR Codes
Post by CarlGundel on Sep 2nd, 2016, 07:56am

If the idea is to implement QR codes as a fun project, you might get your toes wet by implementing 3of9 barcodes first (for fun). It's a lot easier. I did it myself years ago.

-Carl
Re: QR Codes
Post by CryptoMan on Sep 13th, 2016, 03:37am

I also did barcode but that's so much simpler.

The question is QR codes.

Why do it in pure LB?

Well, I want it to work in offline mode. You can not always have Internet connection. Or, website can be unavailabe or can stop this service.

After all, many other things can be without LB but here we are trying to show anything can be doable with LB.

I know that making a QR generator is not easy but should be doable. It's a challenge.

Like Rosetta Code: Write a function in LB to generate QR code.
Re: QR Codes
Post by Rod on Sep 13th, 2016, 1:54pm

Andy did another barcode and I posted a compressed barcode so there are several examples to search out. But a QR code would be good.

Currently stalled on the encryption and error checking code.

Might take me a while to work through that so any contributions welcome.
Re: QR Codes
Post by CryptoMan on Sep 30th, 2016, 3:02pm

There are some good tutorials on Internet for QR now and I think it is doable if there is sufficient time.

There is a LUA source code and maybe a LUA>>>LB translator can be written and this code can be converted to LB.

I will do it when I can find some time.
Re: QR Codes
Post by KaylaB on Nov 14th, 2016, 12:08am

This might be of use
http://fukuchi.org/works/qrencode/