BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

Post your working scripts, libraries and tools for AHK v1.1 and older
paulpma
Posts: 65
Joined: 08 Sep 2018, 22:05

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

30 Apr 2021, 09:14

Thank you for your reply.
Lamar
Posts: 2
Joined: 22 Jul 2021, 10:34

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

22 Jul 2021, 10:47

@Gio Thank you for this script, it has been very helpful. There is one thing I am trying to add that I can't figure out how to implement, now I have a very basic understanding of how QR codes work so I'm sure I'm just missing something but I've tried everything I can think of. I would like to create a QR code with a (Horizontal Tab) between words so that each word would go into a different cell in Excel but I can't figure out how to add in ASCII control characters, no matter what sequence I add in the QR code just stores the exact letters I input and not control characters. Any chance you could point me in the right direction? Thanks
User avatar
SpeedMaster
Posts: 494
Joined: 12 Nov 2016, 16:09

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

29 Jul 2021, 08:00

thank you for this beautiful script. 8-)
I had fun making an example with a GUI.
It may not be very useful but by taking a screenshot you can get a QR code with a label name.
The size of the image (screenshot) can change depending on the resolution of the screen but it is easy to adapt the script to your needs.

It is also possible to adjust the position of the label name by pressing the CTRL + ARROW KEYS.

Code: Select all

#SingleInstance, Force
SetBatchLines, -1


gui, font, s20 bold, arial
gui, +resize
gui, add, picture, w500 h500 vpic -border, 
gui, add, edit, wp h30 y+0 center -e0x200 vlabel, LabelName
gui, font,
gui, font, s14
gui, add, edit, w500 h150  vmyedit, 
gui, add, button, gimport vbimport, Paste clipboard
gui, add, button, ggenerate vbgenerate x+10 yp, Generate QR Code

gui, show

START:
return

generate:
gui, submit, nohide
sleep, 200


MATRIX_TO_PRINT := BARCODER_GENERATE_QR_CODE(myedit)
if (MATRIX_TO_PRINT = 1)
{
	Msgbox, 0x10, Error, The input message is blank. Please input a message to succesfully generate a QR Code image.
	Goto START
}

If MATRIX_TO_PRINT between 1 and 7
{
	Msgbox, 0x10, Error, ERROR CODE: %MATRIX_TO_PRINT% `n`nERROR CODE TABLE:`n`n1 - Input message is blank.`n2 - The Choosen Code Mode cannot encode all the characters in the input message.`n3 - Choosen Code Mode does not correspond to one of the currently indexed code modes (Automatic, numeric, alphanumeric or byte).`n4 - The choosen forced QR Matrix version (size) cannot encode the entire input message using the choosen ECL Code_Mode. Try forcing a higher version or choosing automated version selection (parameter value 0).`n5 - The input message is exceeding the QR Code standards maximum length for the choosen ECL and Code Mode.`n6 - Choosen Error Correction Level does not correspond to one of the standard ECLs (L, M, Q and H).`n7 - Forced version does not correspond to one of the QR Code standards versions.
	Goto START
}

	; Start gdi+
	If !pToken := Gdip_Startup()
	{
		MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
		ExitApp
	}

	pBitmap := Gdip_CreateBitmap(MATRIX_TO_PRINT.MaxIndex() + 8, MATRIX_TO_PRINT.MaxIndex() + 8) ; Adding 8 pixels to the width and height here as a "quiet zone" for the image. This serves to improve the printed code readability. QR Code specs require the quiet zones to surround the whole image and to be at least 4 modules wide (4 on each side = 8 total width added to the image). Don't forget to increase this number accordingly if you plan to change the pixel size of each module.
	G := Gdip_GraphicsFromImage(pBitmap)
	Gdip_SetSmoothingMode(pBitmap, 3)
	pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
	Gdip_FillRectangle(G, pBrush, 0, 0, MATRIX_TO_PRINT.MaxIndex() + 8, MATRIX_TO_PRINT.MaxIndex() + 8) ; Same as above.
	Gdip_DeleteBrush(pBrush)

	Loop % MATRIX_TO_PRINT.MaxIndex() ; Acess the Rows of the Matrix
	{
		CURRENT_ROW := A_Index
		Loop % MATRIX_TO_PRINT[1].MaxIndex() ; Access the modules (Columns of the Rows).
		{
			If (MATRIX_TO_PRINT[CURRENT_ROW, A_Index] = 1)
			{
				Gdip_SetPixel(pBitmap, A_Index + 3, CURRENT_ROW + 3, 0xFF000000) ; Adding 3 to the current column and row to skip the quiet zones.
			}
		}
	}
	StringReplace, FILE_NAME_TO_USE, myedit, `" ; We can't use all the characters that byte mode can encode in the name of the file. So we are replacing them here (if they exist).
	FILE_PATH_AND_NAME := A_ScriptDir . "\" . SubStr(RegExReplace(FILE_NAME_TO_USE, "[\t\r\n\\\/\`:\`?\`*\`|\`>\`<]"), 1, 20) . ".png" ; Same as above. We will only use the first 20 characters for the file name in this example.

	
	; Create a GDI bitmap from the GDIP bitmap
	hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)

	GuiControl, , Pic, % "HBITMAP:*" hBitmap
	sleep, 200
	
	guicontrol, movedraw, label, % " y" getcontrol("pic", "yh")-10
	guicontrol, movedraw, myedit, % " y" getcontrol("label", "yh")+40
	guicontrol, movedraw, bgenerate, % " y" getcontrol("myedit", "yh")+10
	guicontrol, movedraw, bimport, % " y" getcontrol("myedit", "yh")+10

	
	; Gdip_SaveBitmapToFile(pBitmap, FILE_PATH_AND_NAME)
	Gdip_DisposeImage(pBitmap)
	Gdip_DeleteGraphics(G)
	Gdip_Shutdown(pToken)

; MsgBox,0,Success,Created QR Code in file`n%FILE_PATH_AND_NAME%
Goto START
Return

^up::
guicontrol, movedraw, label, % " y" getcontrol("label", "y")-1
return

^down::
guicontrol, movedraw, label, % " y" getcontrol("label", "y")+1
return

^left::
guicontrol, movedraw, label, % " x" getcontrol("label", "x")-1
return

^right::
guicontrol, movedraw, label, % " x" getcontrol("label", "x")+1
return


import:
clipboard = %clipboard%
guicontrol,, myedit, % clipboard
return


getcontrol(crtname, what)
{
 guicontrolget, out,  Pos, %crtname%

 if (what="x")
 return % outx

 if (what="y")
 return % outy

 if (what="w")
 return % outW

 if (what="h")
 return % outH

 if (what="yh")
 return % outy + outH 

 if (what="xw")
 return % outx + outW
}

#Include %A_ScriptDir%/BARCODER.ahk
;#Include %A_ScriptDir%/GDIP.ahk

image.png
image.png (26.21 KiB) Viewed 3469 times
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

29 Jul 2021, 17:58

Thanks for the example with a GUI @SpeedMaster :thumbup:

I was unable to run it out-of-the-box though. The button controls are rendered outside my computers screen area and the image is getting blurred. Not sure why this is happening :?
Spoiler
Lamar wrote:
22 Jul 2021, 10:47
@Gio Thank you for this script, it has been very helpful. There is one thing I am trying to add that I can't figure out how to implement, now I have a very basic understanding of how QR codes work so I'm sure I'm just missing something but I've tried everything I can think of. I would like to create a QR code with a (Horizontal Tab) between words so that each word would go into a different cell in Excel but I can't figure out how to add in ASCII control characters, no matter what sequence I add in the QR code just stores the exact letters I input and not control characters. Any chance you could point me in the right direction? Thanks

Hello @Lamar. Based on you input, i have run some tests and the library is generating tabspaces in messages no problem. That being said, i can think of three possibilities for this issue you are reporting:
1. the use of the inputbox examples as finished code
2. the choice of reader (decoder)
3. MS excel is NOT interpreting the tabspaces as cell divisions

Here are the descriptions and solutions:

1. The example code in the OP uses a simple standard AHK inputbox to collect the message. Tab keypresses are NOT registered in AHKs standard inputboxes, rather they are interpreted as a command to change the current control in focus. HOWEVER, you can pass the message directly to the BARCODER_GENERATE_QR_CODE() function in your script instead, which means tabspaces will be included in the message if they are written according to AHK syntax.


Example: generating a QR Code whose message is hardcoded and uses tabspaces instead of simple whitespaces:

Code: Select all

#SingleInstance, Force
SetBatchLines, -1

START:
Test := "this`tmessage`tontains`ttabspaces`tinstead`tof`tsimple`twhitespaces" ; THIS IS THE MESSAGE

MATRIX_TO_PRINT := BARCODER_GENERATE_QR_CODE(test)
if (MATRIX_TO_PRINT = 1)
{
	Msgbox, 0x10, Error, The input message is blank. Please input a message to succesfully generate a QR Code image.
	Goto START
}

If MATRIX_TO_PRINT between 1 and 7
{
	Msgbox, 0x10, Error, ERROR CODE: %MATRIX_TO_PRINT% `n`nERROR CODE TABLE:`n`n1 - Input message is blank.`n2 - The Choosen Code Mode cannot encode all the characters in the input message.`n3 - Choosen Code Mode does not correspond to one of the currently indexed code modes (Automatic, numeric, alphanumeric or byte).`n4 - The choosen forced QR Matrix version (size) cannot encode the entire input message using the choosen ECL Code_Mode. Try forcing a higher version or choosing automated version selection (parameter value 0).`n5 - The input message is exceeding the QR Code standards maximum length for the choosen ECL and Code Mode.`n6 - Choosen Error Correction Level does not correspond to one of the standard ECLs (L, M, Q and H).`n7 - Forced version does not correspond to one of the QR Code standards versions.
	Goto START
}

	; Start gdi+
	If !pToken := Gdip_Startup()
	{
		MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
		ExitApp
	}

	pBitmap := Gdip_CreateBitmap(MATRIX_TO_PRINT.MaxIndex() + 8, MATRIX_TO_PRINT.MaxIndex() + 8) ; Adding 8 pixels to the width and height here as a "quiet zone" for the image. This serves to improve the printed code readability. QR Code specs require the quiet zones to surround the whole image and to be at least 4 modules wide (4 on each side = 8 total width added to the image). Don't forget to increase this number accordingly if you plan to change the pixel size of each module.
	G := Gdip_GraphicsFromImage(pBitmap)
	Gdip_SetSmoothingMode(pBitmap, 3)
	pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
	Gdip_FillRectangle(G, pBrush, 0, 0, MATRIX_TO_PRINT.MaxIndex() + 8, MATRIX_TO_PRINT.MaxIndex() + 8) ; Same as above.
	Gdip_DeleteBrush(pBrush)

	Loop % MATRIX_TO_PRINT.MaxIndex() ; Acess the Rows of the Matrix
	{
		CURRENT_ROW := A_Index
		Loop % MATRIX_TO_PRINT[1].MaxIndex() ; Access the modules (Columns of the Rows).
		{
			If (MATRIX_TO_PRINT[CURRENT_ROW, A_Index] = 1)
			{
				Gdip_SetPixel(pBitmap, A_Index + 3, CURRENT_ROW + 3, 0xFF000000) ; Adding 3 to the current column and row to skip the quiet zones.
			}
		}
	}
	StringReplace, FILE_NAME_TO_USE, test, `" ; We can't use all the characters that byte mode can encode in the name of the file. So we are replacing them here (if they exist).
	FILE_PATH_AND_NAME := A_ScriptDir . "\" . SubStr(RegExReplace(FILE_NAME_TO_USE, "[\t\r\n\\\/\`:\`?\`*\`|\`>\`<]"), 1, 20) . ".png" ; Same as above. We will only use the first 20 characters for the file name in this example.
	Gdip_SaveBitmapToFile(pBitmap, FILE_PATH_AND_NAME)
	Gdip_DisposeImage(pBitmap)
	Gdip_DeleteGraphics(G)
	Gdip_Shutdown(pToken)

MsgBox,0,Success,Created QR Code in file`n%FILE_PATH_AND_NAME%
;Goto START
ExitApp
#Include %A_ScriptDir%/BARCODER.ahk
#Include %A_ScriptDir%/GDIP.ahk

2. The second possibility is that you may be using a reader (decoder) that switches tabspaces for whitespaces. This is actually quite common since most readers are designed to decode the message for a human to read. I have found an example decoder that DOES decode the message with it's original tabspaces (tested on an editor that has an option to show special characters):

https://online-barcode-reader.inliteresearch.com/

3. I do NOT have MS Excel installed in my machine because i use LibreOffice instead. But i know that depending on some configs, the text being imported to Excel (or scalc in the case of Libre) may be interpreted differently. Do check if another message with tabspaces copied to clipboard and pasted on excel IS being interpreted as a multi-cell message.

Hopefully i have helped you solve the issue. If not, feel free to ask for further assistance below :thumbup:
Lamar
Posts: 2
Joined: 22 Jul 2021, 10:34

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

03 Aug 2021, 08:24

@Gio
Thanks for taking the time to look into it and reply. It seems to be possibility #1 that you mentioned because I used your hardcoded example and it worked perfectly. Thanks so much for your help.
Mr MG
Posts: 14
Joined: 07 Dec 2021, 04:14

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

07 Dec 2021, 04:17

Anyone has the same working script please?
this one says "QR Code image successfully created!" but there is nothing.
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

07 Dec 2021, 04:27

Mr MG wrote:Anyone has the same working script please?
See these two recent posts:

viewtopic.php?f=76&t=97338&p=432767#p432624
viewtopic.php?f=76&t=97338&p=432767#p432872

Regards, Joe
Mr MG
Posts: 14
Joined: 07 Dec 2021, 04:14

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

07 Dec 2021, 04:50

JoeWinograd wrote:
07 Dec 2021, 04:27
Mr MG wrote:Anyone has the same working script please?
See these two recent posts:

viewtopic.php?f=76&t=97338&p=432767#p432624
viewtopic.php?f=76&t=97338&p=432767#p432872

Regards, Joe
None of them working with me, it says success but did not save any QR image!
I'll grateful to you if you make an example for me.
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

07 Dec 2021, 12:18

Mr MG wrote:I'll grateful to you if you make an example for me.
I already did that in the two posts that I mentioned above. Did you download the latest BARCODER.ahk and Gdip.ahk, as well as my GenerateQRcode.ahk and TestQRcodeFunction.ahk? Also, are you on the latest AutoHotkey v1.1.33.10? If so, it should work...at least, it works perfectly here. If it is not working for you, please post all four of those scripts. One other thing...if you used my example script as is, the output file is in A_ScriptDir...is that writable for you? Regards, Joe
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

07 Dec 2021, 13:56

Btw, this is the QR code that gets generated on my W10 system via the four scripts noted earlier (but with the third param 10 instead of 25 and the whole image cropped from its 2100x2970 size that I have hard-coded in the GenerateQRcode function, because that's how I always use it):

testQR20211207125235-size10-cropped.png
testQR20211207125235-size10-cropped.png (5.69 KiB) Viewed 3002 times

Regards, Joe
Mr MG
Posts: 14
Joined: 07 Dec 2021, 04:14

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

08 Dec 2021, 00:01

I re-download Gdip_All.ahk and worked perfectly. THANK YOU SO MUCH
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

08 Dec 2021, 00:32

Great news! You're very welcome. Regards, Joe
Mr MG
Posts: 14
Joined: 07 Dec 2021, 04:14

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

08 Dec 2021, 00:40

One more thing please: since the image output comes with white space, how to fit it to be a perfect size of code itself?
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

08 Dec 2021, 05:56

Mr MG wrote:how to fit it to be a perfect size of code itself?
Let me start by saying that (1) I do not understand how Gio's code works and (2) I am not an expert in Gdip. Thus, there are surely better ways to do this, but I took an approach such that I do not have to mess with Gio's code or know a whole lot about Gdip.

The method is simply to (1) set a large canvas size (I chose 5000x5000); (2)keep track of the minimum and maximum X and Y coordinates inside the loops that create the image; and (3) crop the canvas to those X and Y coordinates, thereby creating an image with only the QR code itself. The new version of the GenerateQRcode function that does this is attached.

Here's an example QR code created directly by the script, i.e., there was no further image manipulation after the script ran:

testQR20211208044514.png
testQR20211208044514.png (3.37 KiB) Viewed 2866 times

Regards, Joe
Attachments
GenerateQRcode.ahk
(3.01 KiB) Downloaded 143 times
Mr MG
Posts: 14
Joined: 07 Dec 2021, 04:14

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

08 Dec 2021, 18:58

JoeWinograd wrote:
08 Dec 2021, 05:56
Mr MG wrote:how to fit it to be a perfect size of code itself?
Let me start by saying that (1) I do not understand how Gio's code works and (2) I am not an expert in Gdip. Thus, there are surely better ways to do this, but I took an approach such that I do not have to mess with Gio's code or know a whole lot about Gdip.

The method is simply to (1) set a large canvas size (I chose 5000x5000); (2)keep track of the minimum and maximum X and Y coordinates inside the loops that create the image; and (3) crop the canvas to those X and Y coordinates, thereby creating an image with only the QR code itself. The new version of the GenerateQRcode function that does this is attached.

Here's an example QR code created directly by the script, i.e., there was no further image manipulation after the script ran:


testQR20211208044514.png


Regards, Joe
Works like charm .. I really appreciate you.
User avatar
JoeWinograd
Posts: 2198
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

08 Dec 2021, 23:53

Mr MG wrote:
08 Dec 2021, 18:58
Works like charm .. I really appreciate you.
Glad to hear it! You're very welcome. Regards, Joe
just me
Posts: 9451
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

12 Dec 2021, 12:23

Hi, I just played a bit with this amazing script and found two errors:
  1. Code: Select all

    	if (CHOOSEN_CODE_MODE = 2)
    	{
    		If !(RegExMatch(MESSAGE_TO_ENCODE, "[^A-Z0-9`$`%`*`+`-`.`/`:`\ ]") = 0)
    
    The RegExMatch needle contains an invalid character \ which (afaik) is not valid for the ALPHANUMERIC_MODE.
  2. Code: Select all

    CONVERT_TO_BYTE_ENCODING(MESSAGE_TO_ENCODE)
    AFAIK, byte encoding only supports the ISO-8859-1 character set. It might produce errors with AHK Unicode strings.
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

12 Dec 2021, 21:07

Thanks for the feedback @just me and glad you found the library useful :thumbup:

1. I guess i may have missed that. Will correct as soon as possible. Thanks for pointing it out.

2. Byte mode is actually just raw binary data. It can even be used to encode images and other types of files. The library contains a Qr Code Generator, which should be able to encode any binary data in this form (not just text). When it comes to QR Code text readers however, you may be right about their usage of ISO 8859-1 as a means to interpret bytes as text in byte mode. But even in that case, there may still be exceptions:

Here is some info from this site:
If there are characters in the input string that can't be encoded in ISO 8859-1, you may be able to encode it in UTF-8 instead, because some QR code readers are able to detect and correctly display UTF-8 encoding in byte mode without requiring any ECI escape sequences.
just me
Posts: 9451
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

13 Dec 2021, 05:01

Hi @Gio,
Gio wrote:The library contains a Qr Code Generator, which should be able to encode any binary data in this form (not just text).
It isn't because you use string functions for the data.

Code: Select all

	Current_Group := SubStr(Message_Left, 1, 1)
reads single characters (2 bytes in Unicode).

Code: Select all

Asc(Current_Group)
returns a value in the range of 0 to 0xFFFF in this case.

If you convert the stringto UTF-8 you need
  1. to use NumGet(MESSAGE_TO_ENCODE, Offset, "UChar") instead of SubStr()
  2. an appropriate QR code reader.
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: BARCODER - Create 1D and 2D Barcodes (QRCode , C39,etc)

13 Dec 2021, 16:30

Okay, thanks for reporting this @just me , i will look into it :thumbup:

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: Google [Bot] and 205 guests