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

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

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

10 Dec 2014, 19:29

Hello there :angel:

Hello World !.png
Hello World !.png (869 Bytes) Viewed 12798 times

Click :arrow: here if you wish to know more about QR Codes and how they can help you automate logistical processes in your company.

About a month ago (on november 2014) a major third-party system update in my company required us to change label barcodes from 1D to 2D due to limited label dimensions and increased data string size. So i was required to create a QR generator capable of encoding strings of 32 numbers.

Four days later i already had a fixed version 2-H (the number is the QR Code version, and refers to the size and capacity, while the letter stands for the Error Correction Level in the code - 30% in this case) numeric strings QR Code generator fully coded in AutoHotkey. The increase in reading speed of the printed labels was so good that i promptly adopted the task of creating a full QR Code library as a side project. Later on, i also decided to drop in 1D barcode creation as a plus. :thumbup:


So here it is:

Barcode Generator Library v1.02 by Giordanno Sperotto (BARCODER.ahk) : Download

Main Fuctions (simply call these functions to retrieve a 1D (CODE39/CODE ITF/CODE 128B) or 2D (QR CODE) array/table object that contains the indexed monochrome pixel values of a barcode image - Object[Column] for 1D, Object[Row,Column] for 2D barcodes):

BARCODER_GENERATE_CODE_39(MESSAGE_TO_ENCODE) - Retrieve a 1D object representing a CODE39 row.
BARCODER_GENERATE_CODE_ITF(MESSAGE_TO_ENCODE) - Retrieve a 1D object representing an interleaved 2 of 5 row.
BARCODER_GENERATE_CODE_128B(MESSAGE_TO_ENCODE) - Retrieve a 1D object representing a CODE128B row.
BARCODER_GENERATE_QR_CODE(MESSAGE_TO_ENCODE) - Retrieve a 2D object representing a QR Code matrix.

Creating an image with the output objects in AutoHotkey should be quite easy thanks to Tic's GDIP Library (http://www.autohotkey.com/forum/viewtopic.php?t=32238). See the examples below the Library code.


Example 1: Generating a 1D Code39 Barcode (Requires BARCODER.ahk - Link above - and GDIP.ahk - Link above - to be present in the same directory as the script).
If you are using Unicode64 versions of AutoHotkey use the file GDIP_All.ahk in place of GDIP.ahk and adjust the #Include lines accordingly. Download link is in the same topic.

Code: Select all

#SingleInstance, Force
SetBatchLines, -1

START:
inputbox, Test,, Type in a message and a corresponding CODE39 Barcode image will be generated and saved in the scripts directory.

MATRIX_TO_PRINT := BARCODER_GENERATE_CODE_39(test)

if (MATRIX_TO_PRINT = 1)
{
	Msgbox, 0x10, Error, The input message is either blank or contains characters that cannot be encoded in CODE_39. You can only encode the following characters in CODE39: UPPERCASE letters, Digits (0-9) and symbols `$, `%, `+, `-, `. and `/. Please adjust the input message accordingly.
	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
}

HEIGHT_OF_IMAGE := 20 ; 20 is the arbitrary height of the Barcode image for this example. You can chage it to any number to increase/decrease the height of the image. Since a scanner must get an accurate vision of a full line, a taller image may offer a higher chance that a physically damaged print will have at least 1 fully readable line (This should not be confused with QR Codes Error Correction Level protection though).

pBitmap := Gdip_CreateBitmap(MATRIX_TO_PRINT.MaxIndex() + 8, HEIGHT_OF_IMAGE) ; Adding 8 pixels to the width here as a "quiet zone" for the image. This serves to improve the printed code readability.
G := Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(pBitmap, 3)
pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
Gdip_FillRectangle(G, pBrush, 0, 0, MATRIX_TO_PRINT.MaxIndex() + 8, HEIGHT_OF_IMAGE) ; Same as above
Gdip_DeleteBrush(pBrush)

	
Loop % HEIGHT_OF_IMAGE
{
	CURRENT_ROW := A_Index
	Loop % MATRIX_TO_PRINT.MaxIndex()
	{
		CURRENT_COLUMN := A_Index
		If (MATRIX_TO_PRINT[A_Index] = 1)	
		{
			Gdip_SetPixel(pBitmap, CURRENT_COLUMN + 3, CURRENT_ROW, 0xFF000000) ; Adding 3 to the current column and the current row to skip the quiet zones.
		}
	}
}
	
CURRENT_ROW := "", CURRENT_COLUMN := ""
	
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, CODE39 image succesfully created!
Goto START

Return
#Include %A_ScriptDir%/BARCODER.ahk
#Include %A_ScriptDir%/GDIP.ahk
Example 2: Generating a 2D QR Code Barcode (Requires BARCODER.ahk - Link above - and GDIP.ahk - Link above - to be present in the same directory as the script).
If you are using Unicode64 versions of AutoHotkey use the file GDIP_All.ahk in place of GDIP.ahk and adjust the #Include lines accordingly. Download link is in the same topic.

Code: Select all

#SingleInstance, Force
SetBatchLines, -1

START:
inputbox, Test,, Type in a message and a corresponding QR Code image will be generated and saved in the scripts directory.

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
Return
#Include %A_ScriptDir%/BARCODER.ahk
#Include %A_ScriptDir%/GDIP.ahk
Example 3: Generating a 1D Interleaved 2 of 5 Barcode (Requires BARCODER.ahk - Link above - and GDIP.ahk - Link above - to be present in the same directory as the script).
If you are using Unicode64 versions of AutoHotkey use the file GDIP_All.ahk in place of GDIP.ahk and adjust the #Include lines accordingly. Download link is in the same topic.

Code: Select all

#SingleInstance, Force
SetBatchLines, -1


START:
inputbox, Test,, Type in a message and a corresponding CODE INTERLEAVED 2 OF 5 Barcode image will be generated and saved in the scripts directory.

If (Test = "")
{
	msgbox, 0x10, Error, The input message is blank. Please insert a message to succesfully generate a CODE_ITF image. 
	Goto START
}

MATRIX_TO_PRINT := BARCODER_GENERATE_CODE_ITF(test)

if (MATRIX_TO_PRINT = 1)
{
	msgbox, 0x10, Error, The input string contains characters that cannot be encoded in an INTERLEAVED 2 OF 5 Barcode. Please correct the message or choose another type of barcode. `n`nYou can only encode numeric strings (0-9) in an INTERLEAVED 2 OF 5 Barcode.
   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
}

HEIGHT_OF_IMAGE := 20 ; 20 is the arbitrary height of the Barcode image for this example. You can chage it to any number to increase/decrease the height of the image. Since a scanner must get an accurate vision of a full line, a taller image may offer a higher chance that a physically damaged print will have at least 1 fully readable line (This should not be confused with QR Codes Error Correction Level protection though).

pBitmap := Gdip_CreateBitmap(MATRIX_TO_PRINT.MaxIndex() + 8, HEIGHT_OF_IMAGE) ; Adding 8 pixels here as a "quiet zone" for the image. This serves to improve the printed code readability.
G := Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(pBitmap, 3)
pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
Gdip_FillRectangle(G, pBrush, 0, 0, MATRIX_TO_PRINT.MaxIndex() + 8, HEIGHT_OF_IMAGE)
Gdip_DeleteBrush(pBrush)

   
Loop % HEIGHT_OF_IMAGE
{
   CURRENT_ROW := A_Index
   Loop % MATRIX_TO_PRINT.MaxIndex()
   {
      CURRENT_COLUMN := A_Index
      If (MATRIX_TO_PRINT[A_Index] = 1)   
      {
         Gdip_SetPixel(pBitmap, CURRENT_COLUMN + 3, CURRENT_ROW, 0xFF000000) ; Adding 3 to the current column to skip the quiet zone.
      }
   }
}
   
CURRENT_ROW := "", CURRENT_COLUMN := ""
   
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, CODE2OF5 image succesfully created!
Goto START

Return
#Include %A_ScriptDir%/BARCODER.ahk
#Include %A_ScriptDir%/GDIP.ahk
Example 4: Generating a 1D Code128 Barcode (Requires BARCODER.ahk - Link above - and GDIP.ahk - Link above - to be present in the same directory as the script).
If you are using Unicode64 versions of AutoHotkey use the file GDIP_All.ahk in place of GDIP.ahk and adjust the #Include lines accordingly. Download link is in the same topic.

Code: Select all

#SingleInstance, Force
SetBatchLines, -1
 
START:
inputbox, Test,, Type in a message and a corresponding CODE128 Barcode image will be generated and saved in the scripts directory.
 
MATRIX_TO_PRINT := BARCODER_GENERATE_CODE_128B(test)
 
if (MATRIX_TO_PRINT = 1)
{
	Msgbox, 0x10, Error, The input message is either blank or contains characters that cannot be encoded in CODE_128B.
	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
}
 
HEIGHT_OF_IMAGE := 20 ; 20 is the arbitrary height of the Barcode image for this example. You can chage it to any number to increase/decrease the height of the image. Since a scanner must get an accurate vision of a full line, a taller image may offer a higher chance that a physically damaged print will have at least 1 fully readable line (This should not be confused with QR Codes Error Correction Level protection though).
 
pBitmap := Gdip_CreateBitmap(MATRIX_TO_PRINT.MaxIndex() + 8, HEIGHT_OF_IMAGE) ; Adding 8 pixels to the width here as a "quiet zone" for the image. This serves to improve the printed code readability.
G := Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(pBitmap, 3)
pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
Gdip_FillRectangle(G, pBrush, 0, 0, MATRIX_TO_PRINT.MaxIndex() + 8, HEIGHT_OF_IMAGE) ; Same as above
Gdip_DeleteBrush(pBrush)
 
 
Loop % HEIGHT_OF_IMAGE
{
	CURRENT_ROW := A_Index
	Loop % MATRIX_TO_PRINT.MaxIndex()
	{
		CURRENT_COLUMN := A_Index
		If (MATRIX_TO_PRINT[A_Index] = 1)	
		{
			Gdip_SetPixel(pBitmap, CURRENT_COLUMN + 3, CURRENT_ROW, 0xFF000000) ; Adding 3 to the current column and the current row to skip the quiet zones.
		}
	}
}
 
CURRENT_ROW := "", CURRENT_COLUMN := ""
 
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, CODE128B image succesfully created!
Goto START
 
Return
#Include %A_ScriptDir%/BARCODER.ahk
#Include %A_ScriptDir%/GDIP.ahk
Some notes about QR Codes and the available options:
1 - This library is fully coded in AutoHotkey (no external dependencies).
2 - QR Codes can encode up to: 7089 characters long numeric strings (0-9), 4296 characters long AlphaNumeric strings or 2953 Bytes. (The later is interpreted through the full ASCII list of characters if a text reader is used.)
3 - You can force the Version (size) of the QR matrix in the fourth parameter of the GENERATE_QR_CODE() function if the choosen version is big enougth to encode all the data you have entered (this may be usefull if you are looking for a standard size output regardless of string length). Be careful though: If a forced version has no capacity to fully encode the input message, no QR Matrix will be generated at all. Available QR Code versions and corresponding parameter values: 1 to 40.
4 - The standard Error Correction Level (ECL) for the GENERATE_QR_CODE() function is set to M (15%). You can force another ECL level in the third parameter of the function if you wish more ECL (though this may end up generating a bigger matrix) or less (outputing a smaller matrix). Available ECLs for the QR Codes standard are L (7%), M (15%), Q (25%) and H (30%). Parameter values are 1 for L, 2 for M, 3 for Q and 4 for H.
5 - The examples above output QR Code images whose modules (individual "points") are 1 pixel wide. It is possible, however, to use loops to generate an image with modules 2 pixels wide, 3 pixels wide, or any other dimensions you like. Check this post for an example on how to change module sizes.
6 - You can force an encoding mode in the second parameter of the GENERATE_QR_CODE() function if that mode is capable of encoding all the data you have entered. That is not recomended, however, as the function already uses the best option for each case and if a forced encoding mode is unable to encode all the characters in the input message, no QR Matrix will be generated at all.
7 - If you wish to implement a QR Code routine, there is usually no need to worry about coding a QR Code reader function since the 2D scanners available in the market usually ship bundled with reading and auto-typing softwares.
8 - If your routine absolutely needs to have your PC decoding the QR Codes without a scanner though, there are some freeware tools that will do the job for you. ZBar, in example (and as mentioned by JoeWinograd), decodes QR Codes in image files or straight from your PCs webcam, and is able to output the decoded messages to the CMD (which can than be retrieved by AutoHotkey using CMDRet()). You can check an example here.

Known limitations of this version:
Kanji (Japanese/Korean/Chinese Characters) Encoding in QR Codes is currently NOT supported natively. HOWEVER, you can still encode Kanji in QR Codes using BARCODER and this funcion by Zhang.

Aditional credits:
1 - Infogulch, for Bin() and Dec() - http://www.autohotkey.com/board/topic/49990-binary-and-decimal-conversion/
2 - Tic for the Gdip Library (used in the examples and recomended as the choice AHK image editor tool) - http://www.autohotkey.com/forum/viewtopic.php?t=32238
3 - AlphaBravo, for the Interleaved 2 of 5 and Code128 barcode functions.
4 - JoeWinograd, for suggestions and examples regarding reading QR Codes without a scanner.
5 - Zhang, for a function and an example on how to encode Kanji in QR Codes using this library.

Feel free to drop in any questions.

Best wishes :angel:

CHANGELOG:
11 December 2014:
First version is up. Supports CODE39 and QR Code barcode generation. Examples added to the post.
23 December 2014:
1 - Added Interleaved 2 of 5 Functions by AlphaBravo.
2 - Changed the lib and function names to allow MyLib_MyFunc syntax compatibility.
25 December 2014:
Fixed a typo in the code generating incorrect version 11-M matrixes.
27 December 2014:
1 - Ran a test on each of the 40 QR Code versions, using each of the 4 ECLs for every version. All 160 matrixes generated were found to be perfectly readable.
2 - Changed Library Version to 1.02 to avoid confusion with 1.0, which was generating non-working QR Code version 11 Matrixes.
3 - The Messageboxes warning errors in the QR Code function have been commented out (so that the function can operate silently). The function now returns all errors as values 1 to 7. Check the notes above the function code if you wish to see/manage these errors in your code.
23 June 2016:
Added Code128B functions by AlphaBravo.
Last edited by Gio on 02 Oct 2017, 15:51, edited 54 times in total.
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

11 Dec 2014, 12:22

So what is a QR Code?

QR Code stands for Quick Response Code, and it is a 2D (two-dimensional) barcode suitable for storing data into printed labels for later retrieval. The biggest advantages over 1D barcodes are that it can encode a lot more data than a regular 1D barcode (roughly 3kB of data can be encoded in this way in a relativelly small QR Code image) and that it includes a more advanced Error Correction process. As with the regular 1D barcode images, it is important to notice that a QR Code image can be printed on any low cost stick label paper, making it quite cheap to control physical objects using them.

Another similarity is that most 2D barcode scanners available in the market will ship bundled with software that decodes and auto-types the content in the QR images, making it usually unnecessary for programmers to code image decoding routines at all. Even the most common cell phones nowadays have access to free downloadable apps that will decode QR Code images straight from their back camera.


What is it good for?

Applications vary. Suppose you have a company that either fabricates or buy products for sale, and you need a way to store information on product boxes (such as instructions for assembly, info over that product such as expiring date, or anything else you like) that should be retrieved sometime later in the process. Instead of printing written text directly into the boxes or even printing a huge label with written instructions, you can simply print a small QR Code image and all this information will be stored in it, so that it can be decoded by handheld readers and displayed to any user anytime you wish.

Decoding is incredibly fast by up-to-date scanners !

Decoding around 1Kb of text took me about 5-6 secs on a regular Iphone5 quick test. For comparison, if a user had to type in 1.000 characters, considering average typing speed, it would take around 5-6 minutes of continuous typing. How many man-hours worth of typing written text could this save in your company?

QR Codes can store encrypted messages !

Instead of encoding plain text to a QR Code, you can encode encrypted text into it, so that only your system is able to recover the data stored in the printed label. This ensures data security and even allows you to develop a routine wich guarantees that a user has scanned a label (by making it impossible for the user to guess the correct value to be inserted).

QR Codes are ideal for controling logistical processes !

Suppose that you need a way to make sure that a user has completed a logistical routine, such as moving some product from a place to another inside a huge warehouse on specific times. You can have the system print a label with a corresponding code to be sticked in the products box during storage process, and have another user scan that label at a specific PC located in the exit door of the warehouse whenever an order has been issued for that product. This will make sure that the correct item has been moved up to that location (because only that PC has the checking routine and it will check the code in the product) and that it has been brought up to that place when the order was issued (because the system may not accept the readed code if no order related to it exists and because the data may be encrypted to allow no user guesses).

Lot's more up to your own creativity !

Possible usage goes far beyond these examples, but time is short and for the moment, i'm leaving the thinking part to you. Feel free to post in any ideas for QR Code usage if you like, or to ask any questions about how to implement a given routine. Once again, my best wishes :angel:
Last edited by Gio on 02 Jan 2015, 17:44, edited 27 times in total.
User avatar
joedf
Posts: 8937
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

11 Dec 2014, 13:00

I gotta say... very cool ;)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

15 Dec 2014, 16:17

joedf wrote:I gotta say... very cool ;)
Skywalker wrote:Great !
Thanks for the Feedback Joedf and Skywalker :thumbup:
User avatar
AlphaBravo
Posts: 586
Joined: 29 Sep 2013, 22:59

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

15 Dec 2014, 17:49

This is absolutely great, I guess I won't be using 3rd party software anymore.
I will chip in code for Interleaved 2 of 5, feel free to add it to your library.

Code: Select all

GENERATE_CODE_ITF(NUMBER_TO_ENCODE, Add_Check_Sum:=0){
	if NUMBER_TO_ENCODE is not digit
		return 1
	if Add_Check_Sum
		NUMBER_TO_ENCODE := Add_Check_Sum(NUMBER_TO_ENCODE)
	
	; http://en.wikipedia.org/wiki/Interleaved_2_of_5
	Codes := "NNWWN,WNNNW,NWNNW,WWNNN,NNWNW,WNWNN,NWWNN,NNNWW,WNNWN,NWNWN"

	; assign "Narrow/Wide" codes to numbers 0-9
	CODE_ITF_TABLE := [], MATRIX_TO_PRINT := [], BarWidth := []
	for k, v in StrSplit(Codes, ",")
		CODE_ITF_TABLE[A_Index-1] := v

	; an odd number of digits is encoded by adding a "0" as first digit
	NUMBER_TO_ENCODE := RegExReplace(NUMBER_TO_ENCODE, "^(?=\d(\d\d)*$)", "0")
	
	; assign bar/space width to number
	for k, v in StrSplit(NUMBER_TO_ENCODE)
	{
		Pair .= v
		if Mod(A_Index,2)
			continue
		Code1 := StrSplit(CODE_ITF_TABLE[SubStr(Pair,1,1)])	, 	Code2 := StrSplit(CODE_ITF_TABLE[SubStr(Pair, 0) ])	, Pair := ""	
		; interleave bar/space widths, (W/N to bars) and (w/n to spaces)
		loop, 5										
			BarWidth.Insert(Code1[A_Index])		, 	BarWidth.Insert(RegExReplace(Code2[A_Index], "(.)", "$L1"))
	}

	for k, v in StrSplit("1010")		; add prefix
		MATRIX_TO_PRINT.Insert(v)

	; assign matrix
	for i, v in BarWidth {
		if (v == "W")
			loop, 3
				MATRIX_TO_PRINT.Insert("1")
		else if (v == "N")
			MATRIX_TO_PRINT.Insert("1")
		else if (v == "w")
			loop, 3
				MATRIX_TO_PRINT.Insert("0")
		else if (v == "n")
			MATRIX_TO_PRINT.Insert("0")
	}

	for k, v in StrSplit("11101")		; add suffix
		MATRIX_TO_PRINT.Insert(v)
	return MATRIX_TO_PRINT
}

Add_Check_Sum(num){ ; http://en.wikipedia.org/wiki/Universal_Product_Code#Check_digits
	for k, v in StrSplit(num)
		if mod(A_Index, 2)
			odd += v
		else
			even += v
	return num . 10-mod(odd*3+even, 10)
}
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

15 Dec 2014, 18:58

AlphaBravo wrote:This is absolutely great, I guess I won't be using 3rd party software anymore.
I will chip in code for Interleaved 2 of 5, feel free to add it to your library.
Excellent. Will certainly add it and credit you accordingly AlphaBravo :thumbup:

Just a minor question: i am getting no reading when the input message is 4 digits or less. Is this unintended?

Thanks for the add-on.
User avatar
AlphaBravo
Posts: 586
Joined: 29 Sep 2013, 22:59

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

15 Dec 2014, 22:15

Gio wrote:Just a minor question: i am getting no reading when the input message is 4 digits or less. Is this unintended?
I ran a quick test and did not see any problem.

Code: Select all

Clipboard := ""
loop, 10
{
	res := ""
	for k, v in GENERATE_CODE_ITF(A_Index-1)
		res .= v
	Clipboard .= A_Index-1 "`t" res "`n"
}
MsgBox % Clipboard

/*
0	101010101110001110001011101
1	101010001011101110100011101
2	101010100011101110100011101
3	101010001000111011101011101
4	101010101110001110100011101
5	101010001011100011101011101
6	101010100011100011101011101
7	101010101110111000100011101
8	101010001011101110001011101
9	101010100011101110001011101
*/
I suggest to use Libraries of Functions with MyPrefix_MyFunc and build a nice GUI around it
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

16 Dec 2014, 11:13

AlphaBravo wrote:I ran a quick test and did not see any problem.
I'll attach an image for input message 5.

5 is 101010001011100011101011101 right?
5.png
5 - 101010001011100011101011101
5.png (331 Bytes) Viewed 41482 times
No reading for that image. Both using Zxing Decoder (http://zxing.org/w/decode.jspx) and another scanner i have on my Iphone.

I do get a reading whenever i input a string 5 chars long or longer on your code though.

EDIT: Got a succesful reading using another online scanner (http://online-barcode-reader.inliterese ... fault.aspx). Don't know what caused ZXing and my phone to fail the reading :crazy:

Consider it solved though.
AlphaBravo wrote:I suggest to use Libraries of Functions with MyPrefix_MyFunc and build a nice GUI around it
Will look into it.
User avatar
AlphaBravo
Posts: 586
Joined: 29 Sep 2013, 22:59

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

16 Dec 2014, 14:50

I have used a third party program and an online barcode generatora nd both came up with and same results matching what you posted. maybe it is a limitation on ITF
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: Barcode Gen - Create 1D and 2D Barcodes (QR Code , C39,

16 Dec 2014, 15:39

Here is your example code as a QR_CODE example:

Code: Select all

#SingleInstance, Force
SetBatchLines, -1

START:
inputbox, Test,, Type in a message and a corresponding QR-CODE image will be generated and saved in the scripts directory.

MATRIX_TO_PRINT := GENERATE_QR_CODE(test)

if (MATRIX_TO_PRINT = 1)
{
   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.1.MaxIndex(), MATRIX_TO_PRINT.MaxIndex())
G := Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(pBitmap, 3)
pBrush := Gdip_BrushCreateSolid(0xFFFFFFFF)
Gdip_FillRectangle(G, pBrush, 0, 0, MATRIX_TO_PRINT.1.MaxIndex(), MATRIX_TO_PRINT.MaxIndex())
Gdip_DeleteBrush(pBrush)

   
Loop % MATRIX_TO_PRINT.MaxIndex()
{
   CURRENT_ROW := A_Index-1
   CURRENT_ROW_DATA := MATRIX_TO_PRINT[A_Index]
   Loop % CURRENT_ROW_DATA.MaxIndex()
      If (CURRENT_ROW_DATA[A_Index] = 1)   
         Gdip_SetPixel(pBitmap, A_Index-1, CURRENT_ROW, 0xFF000000)
}
   
CURRENT_ROW := "", CURRENT_COLUMN := ""
   
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, "/w+"), 1, 20) . ".png" ; Same as above.
Gdip_SaveBitmapToFile(pBitmap, FILE_PATH_AND_NAME)
Gdip_DisposeImage(pBitmap)
Gdip_DeleteGraphics(G)
Gdip_Shutdown(pToken)

msgbox, 0, Success, QR-CODE image succesfully created!
Goto START

Return
#Include %A_ScriptDir%/BARCODE_GEN.ahk
#Include %A_ScriptDir%/GDIP.ahk
Recommends AHK Studio
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: BARCODER - Create 1D and 2D Barcodes (QR Code , C39,etc

23 Dec 2014, 18:03

UPDATE:
Added Interleaved 2 of 5 Barcode functions by AlphaBravo. Changed the lib and function names to allow Mylib_Myfunc syntax compatibility.
Here is your example code as a QR_CODE example:
Thanks for the new code block syntax Nnnik, it really helps readability :thumbup:
Also, your example works pretty fine. Only issues i got are that you removed the quiet zones (all light-colored areas surrounding the qr code that serve to improve readability)* and using "/w+" RegEx will still allow some characters that cannot be used in file names to be present in the call to Gdip_SaveBitmapToFile() (which means function call failure and no output file for these cases).

*The quiet zones were originally added in the example when i created a canvas image whose dimensions are 8 pixels wider than the dimensions of the QR Matrix. I will add the comments for the corresponding lines now.
User avatar
JoeWinograd
Posts: 2165
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

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

31 Jan 2016, 10:19

Hi Gio,
First, let me say — fantastic piece of code! I'm using your BARCODER to generate alphanumeric QR Codes and Code 39 barcodes — works a charm! Second, a question for you. Are you aware of any AHK code that will read/interpret the alphanumeric string in your QR Code and/or Code 39 and place the value in an AHK variable? I prefer to go with QR Code on this project, but could live with Code 39. The image with the QR Code or Code 39 barcode will be a page of a PDF file, but I can convert that to whatever image file format the code reader/interpreter requires (GIF, JPEG, PNG, TIFF, etc.). I'll post this on the main board later, but thought it made sense to ask you here first, since you are clearly an expert in this subject. Thanks very much, Joe
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

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

31 Jan 2016, 11:54

Hello JoeWinograd.

Glad you've found the library useful :thumbup:

Usually, the reading part is taken care of by the readers device firmware. Almost any 2D barcode scanner available in the market will ship bundled with firmware to read and autotype QR Code messages in your PC (only phones usually don't autotype to PC).

In other words, unless you are planning to engineer a reader device yourself, you probably won't really have to design a reader routine (just have a GUI with an edit control that will receive the autotyped message from the scanner and either a button or g-label to check the input data).

However, if you absolutely NEED to have your own app scanning image files and decoding the strings (do check if you really need it), i think your best bet so far is still an external a DLL file, since i don't know of AHK code for reading barcodes already avaialable. If you absolutely NEED AHK code alone though (if DLL files are not an option), are the images going to be taken by a camera or are they clean outputs such as the ones generated in my examples?

Scripting a function to read camera images will probably be too time consuming, but it really shouldn't be that hard to code a reader for clean outputed CODE39 images in bmp format. If you need guidance to go either way, feel free to ask.
User avatar
JoeWinograd
Posts: 2165
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

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

31 Jan 2016, 12:29

Hi Gio,
Thanks for the fast reply — much appreciated! There is no barcode scanner involved in this project. The situation is that PDF documents are being created with an alphanumeric code on it that identifies the particular PDF document type and another alphanumeric code that identifies the person who will be filling in the document. For example, it may be something like this:

Document ID: ABC-12345
Person ID: 1234567890

The Person will print out the document, fill it in, and then someone else will scan it will a typical desktop scanner (yes, a web form approach is a better idea, and that method exists in the system, but there are cases where the printing/scanning method is needed). When the document is scanned with a typical desktop scanner, a PDF file will be created — probably an image-only PDF, but in some cases it may be a searchable PDF (a PDF with text from an OCR process performed at or after scan time).

My plan is to write an AHK script that the scanning operator will run after scanning a stack of documents. Each document in the stack will have a QR Code (or Code 39 barcode) on the first page which contains the Document ID and Person ID. My script will split the document stack into separate PDFs based on finding a QR Code (or Code 39 barcode), which means that it is the first page of a new PDF. Furthermore, it will name each separate PDF file with the alphanumeric contents of the QR Code (or Code 39 barcode), such as ABC-12345_1234567890.pdf (using the example above).

I have no control over the scanning hardware and software that will be used, so my AHK script must be robust enough to handle the QR Code (or Code 39 barcode) on any type of PDF file (or multi-page TIFF file). I thought about doing this with OCR software, but my expectation is that QR Codes or Code 39 barcodes will provide higher accuracy than OCR.

I think that describes the requirement, but let me know if you need more info to make recommendations. Thanks again, Joe
User avatar
JoeWinograd
Posts: 2165
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

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

31 Jan 2016, 18:13

Hi Gio,
Two things for you: (1) I found a command line tool called ZBar bar code reader that has worked in my tests, so don't worry about the question above. (2) I've been using BARCODER with your example script (Example2-QR_Code.ahk) and it works great, but generates very small QR Codes, somewhere in the 30 pixel range. That hasn't been an issue until now, but now I need a QR Code in the 300 pixel range. How could your example script be modified to generate that? Thanks again, Joe
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

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

31 Jan 2016, 19:10

Great to see that you've found a solution that fast :thumbup:

You can use loops to set a 2D block of pixels for each module in the matrix rather than a single pixel for each module. Bellow is an example that outputs matrixes whose modules are 3 pixels wide (3x3):

Code: Select all

#SingleInstance, Force
SetBatchLines, -1

START:
inputbox, Test,, Type in a message and a corresponding QR Code image will be generated and saved in the scripts directory.

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) * 3, (MATRIX_TO_PRINT.MaxIndex() + 8) * 3) ; 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) * 3, (MATRIX_TO_PRINT.MaxIndex() + 8) * 3) ; 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).
		{
			CURRENT_COLUMN := A_Index
			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.
				Loop 3
				{
					CURRENT_REDIMENSION_ROW := A_Index
					Loop 3
					{
						Gdip_SetPixel(pBitmap, (CURRENT_COLUMN * 3) + 8 + A_Index, (CURRENT_ROW * 3) + 8 + CURRENT_REDIMENSION_ROW, 0xFF000000)
					}
			}
		}
			If (MATRIX_TO_PRINT[CURRENT_ROW, A_Index] = 0) ; White pixels need some more attention too when doing multi pixelwide images.
			{
				Loop 3
				{
					CURRENT_REDIMENSION_ROW := A_Index
					Loop 3
					{
						Gdip_SetPixel(pBitmap, (CURRENT_COLUMN * 3) + 8 + A_Index, (CURRENT_ROW * 3) + 8 + CURRENT_REDIMENSION_ROW, 0xFFFFFFFF)
					}
				}
			}
		}
	}
	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.
	Gdip_SaveBitmapToFile(pBitmap, FILE_PATH_AND_NAME)
	Gdip_DisposeImage(pBitmap)
	Gdip_DeleteGraphics(G)
	Gdip_Shutdown(pToken)

msgbox, 0, Success, QR Code image succesfully created!
Goto START
Return
#Include %A_ScriptDir%/BARCODER.ahk
#Include %A_ScriptDir%/GDIP.ahk
You can use a similar method to make each module in the matrix 4 pixels wide, 5 pixels wide, and any other size you like :thumbup:
User avatar
JoeWinograd
Posts: 2165
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

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

31 Jan 2016, 19:26

OK, that works well — makes the QR Code around 100 pixels. So I changed the four Loop 3 commands to Loop 10, expecting about 300 pixels, but I'm still getting around 100. Something else I need to change?
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

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

31 Jan 2016, 19:40

In the examples method to write the matrix, you will have to adjust:

- The math in the loop (which you correctly guessed - it defines the size of each module).
- The math in the GDIP function that is creating the canvas (so that the canvas is the correct size in pixels).
- The math in the GDIP function that is filling the canvas white (so that the canvas is completely filled with white pixels before we paint the modules in it).
- The math in the Gdip_SetPixel() calls (so that the modules of the matrix are painted in their correct location).

I'll drop in the 10x10 example code:

Code: Select all

#SingleInstance, Force
SetBatchLines, -1
 
START:
inputbox, Test,, Type in a message and a corresponding QR Code image will be generated and saved in the scripts directory.
 
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) * 10, (MATRIX_TO_PRINT.MaxIndex() + 8) * 10) ; 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) * 10, (MATRIX_TO_PRINT.MaxIndex() + 8) * 10) ; 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).
		{
			CURRENT_COLUMN := A_Index
			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.
				Loop 10
				{
					CURRENT_REDIMENSION_ROW := A_Index
					Loop 10
					{
						Gdip_SetPixel(pBitmap, (CURRENT_COLUMN * 10) + 29 + A_Index, (CURRENT_ROW * 10) + 29 + CURRENT_REDIMENSION_ROW, 0xFF000000)
					}
			}
		}
			If (MATRIX_TO_PRINT[CURRENT_ROW, A_Index] = 0) ; White pixels need some more attention too when doing multi pixelwide images.
			{
				Loop 10
				{
					CURRENT_REDIMENSION_ROW := A_Index
					Loop 10
					{
						Gdip_SetPixel(pBitmap, (CURRENT_COLUMN * 10) + 29 + A_Index, (CURRENT_ROW * 10) + 29 + CURRENT_REDIMENSION_ROW, 0xFFFFFFFF)
					}
				}
			}
		}
	}
	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.
	Gdip_SaveBitmapToFile(pBitmap, FILE_PATH_AND_NAME)
	Gdip_DisposeImage(pBitmap)
	Gdip_DeleteGraphics(G)
	Gdip_Shutdown(pToken)
 
msgbox, 0, Success, QR Code image succesfully created!
Goto START
Return
#Include %A_ScriptDir%/BARCODER.ahk
#Include %A_ScriptDir%/GDIP.ahk
Last edited by Gio on 31 Jan 2016, 19:54, edited 2 times in total.
User avatar
JoeWinograd
Posts: 2165
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

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

31 Jan 2016, 19:50

Perfect! Thank you so much. I truly appreciate it! Regards, Joe

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: chinagreenelvis, ntepa and 83 guests