morgan1991
31-01-2022, 23:48
Здравствуйте!
Суть проблемы:
Нужно сгенерировать штрихкод и сохранить его в картинку. В идеале в JPG.
Нужен именно формат EAN-13 из 13 цифр.
Причем хотелось бы не использовать шрифт ean13.ttf. Или как то использовать его без установки в операционную систему. Т.к. нет прав доступа.
Нашел в интернете несколько рабочих вариантов, но они все генерируют только из 12 символьного ШК, а нужно именно 13.
Вот например один из них. Все файлы с UDF во вложении.
; TTF fonts must be installed in system first
#AutoIt3Wrapper_run_obfuscator=y
#Obfuscator_parameters=/so
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <print.au3>
#include <barcode.au3>
$barcode_test = GUICreate("BarCode Test", 601, 174, -1, -1)
GUICtrlCreateLabel("Input:", 11, 10, 30, 17)
$Input = GUICtrlCreateInput("", 41, 8, 120, 21)
GUICtrlCreateLabel("Output:", 171, 10, 38, 17)
$Output = GUICtrlCreateInput("", 209, 8, 120, 21)
GUICtrlSetState(-1, $GUI_DISABLE)
$print = GUICtrlCreateButton("Print", 340, 7, 39, 23)
GUICtrlCreateLabel("Type:", 387, 10, 28, 17)
$type = GUICtrlCreateCombo("", 417, 8, 91, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Code 128|EAN 8|EAN 13|Code 2 of 5 i|Code 3 of 9", "Code 128")
GUICtrlCreateLabel("Size:", 517, 10, 25, 17)
$size = GUICtrlCreateCombo("", 543, 8, 47, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "12|18|24|36|48|60|72", "48")
$barcode = GUICtrlCreateLabel("", 10, 39, 580, 130)
GUICtrlSetFont(-1, 48, 400, 0, "Code 128")
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $type
ChangeFont()
ApplyBarcode()
Case $size
ChangeFont()
Case $print
Print()
EndSwitch
WEnd
Func WM_COMMAND($hWinHandle, $iMsg, $wParam, $lParam)
If _WinAPI_HiWord($wParam) = $EN_CHANGE And _WinAPI_LoWord($wParam) = $Input Then
ApplyBarcode()
EndIf
EndFunc
Func ChangeFont()
Switch GUICtrlRead($type)
Case 'Code 128'
$font_name = 'Code 128'
Case 'EAN 8','EAN 13'
$font_name = 'Code EAN13'
Case 'Code 2 of 5 i'
$font_name = 'Code 2 of 5 interleaved'
Case 'Code 3 of 9'
$font_name = 'Code 3 de 9'
EndSwitch
GUICtrlSetFont($barcode, GUICtrlRead($size), 400, 0, $font_name)
EndFunc
Func ApplyBarcode()
Switch GUICtrlRead($type)
Case 'Code 128'
$barcode_data = barcode_128(GUICtrlRead($Input))
Case 'EAN 8'
$barcode_data = barcode_ean8(GUICtrlRead($Input))
Case 'EAN 13'
$barcode_data = barcode_ean13(GUICtrlRead($Input))
Case 'Code 2 of 5 i'
$barcode_data = barcode_25i(GUICtrlRead($Input))
Case 'Code 3 of 9'
$barcode_data = barcode_39(GUICtrlRead($Input))
EndSwitch
GUICtrlSetData($Output, $barcode_data)
GUICtrlSetData($barcode, $barcode_data)
EndFunc
; print given text on default printer in given size by all available barcode types
Func Print()
$sPrinter = _GetDefaultPrinter()
If $sPrinter = "" Then Return
$hPrintDC = _WinAPI_CreateDC("winspool", $sPrinter)
_InitPrinter($hPrintDC, "Printing Barcodes from AutoIt") ; print job name
$hFont = _CreateFont_Simple('Arial', 12, $FW_BOLD)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 500, 'Input data: ' & GUICtrlRead($Input), 0xFF0000)
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Courier', 10, $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_WinAPI_SetTextColor($hPrintDC, 0x000000)
_TextOut_Centered($hPrintDC, 1400, 'Code 128')
_TextOut_Centered($hPrintDC, 2400, 'EAN 8')
_TextOut_Centered($hPrintDC, 3400, 'EAN 13')
_TextOut_Centered($hPrintDC, 4400, 'Code 2 of 5 i')
_TextOut_Centered($hPrintDC, 5400, 'Code 3 of 9')
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code 128', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 1500, barcode_128(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code EAN13', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 2500, barcode_ean8(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code EAN13', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 3500, barcode_ean13(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code 2 of 5 interleaved', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 4500, barcode_25i(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code 3 de 9', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 5500, barcode_39(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
_DeInitPrinter($hPrintDC)
EndFunc
Вот еще нашел решение, но непонятно на каком языке. Может будет полезно:
PROGRAM
MAP
MODULE('Windows API')
AddFontResource(*CSTRING FontName),RAW,LONG,PASCAL,NAME('AddFontResourceA')
END
EAN13(STRING Barcode), STRING
END
LOC:FontFileName CSTRING(20)
LOC:Barcode1 CSTRING(20)
LOC:Barcode2 CSTRING(20)
LOC:Barcode3 CSTRING(20)
Window WINDOW('Use EAN13 Font'),AT(,,161,140),FONT('MS Sans Serif',8,,FONT:regular),CENTER,GRAY,DOUBLE
STRING(@s20),AT(18,9),USE(LOC:Barcode1)
STRING(@s20),AT(18,48),USE(LOC:Barcode2)
STRING(@s20),AT(18,97),USE(LOC:Barcode3)
END
CODE
LOC:FontFileName = 'EANG000.TTF'
IF NOT AddFontResource(LOC:FontFileName)
MESSAGE('Error on load: ' & LOC:FontFileName,'Warning',ICON:Hand)
END
OPEN(Window)
?LOC:Barcode1{PROP:Font} = 'EanGnivc'
?LOC:Barcode1{PROP:FontSize} = 20
?LOC:Barcode2{PROP:Font} = 'EanGnivc'
?LOC:Barcode2{PROP:FontSize} = 30
?LOC:Barcode3{PROP:Font} = 'EanGnivc'
?LOC:Barcode3{PROP:FontSize} = 40
LOC:Barcode1 = EAN13(2340600973341)
LOC:Barcode2 = EAN13(6945198851772)
LOC:Barcode3 = EAN13(2901214010046)
ACCEPT
END
CLOSE(Window)
EAN13 FUNCTION(STRING Barcode)!, STRING
a LONG(48)
b LONG(65)
c LONG(97)
d LONG(35)
i LONG
Cod LONG,DIM(13,2)
f LONG,DIM(6,10)
strEAN13 STRING(20)
CODE
IF LEN(CLIP(BarCode)) <> 13
MESSAGE('Штрих код за пределами отведенного диапазона')
RETURN ''
END
f[1,0] = a; f[1,1] = a; f[1,2] = a; f[1,3] = a; f[1,4] = a
f[1,5] = a; f[1,6] = a; f[1,7] = a; f[1,8] = a; f[1,9] = a
f[2,0] = a; f[2,1] = a; f[2,2] = a; f[2,3] = a; f[2,4] = b
f[2,5] = b; f[2,6] = b; f[2,7] = b; f[2,8] = b; f[2,9] = b
f[3,0] = a; f[3,1] = b; f[3,2] = b; f[3,3] = b; f[3,4] = a
f[3,5] = b; f[3,6] = b; f[3,7] = a; f[3,8] = a; f[3,9] = b
f[4,0] = a; f[4,1] = a; f[4,2] = b; f[4,3] = b; f[4,4] = a
f[4,5] = a; f[4,6] = b; f[4,7] = b; f[4,8] = b; f[4,9] = a
f[5,0] = a; f[5,1] = b; f[5,2] = a; f[5,3] = b; f[5,4] = b
f[5,5] = a; f[5,6] = a; f[5,7] = a; f[5,8] = b; f[5,9] = b
f[6,0] = a; f[6,1] = b; f[6,2] = b; f[6,3] = a; f[6,4] = b
f[6,5] = b; f[6,6] = a; f[6,7] = b; f[6,8] = a; f[6,9] = a
LOOP i = 1 TO 13
Cod[i, 1] = SUB(BarCode, i, 1)
END
LOOP i = 2 TO 7
Cod[i, 2] = f[i - 1, Cod[1, 1]]
END
strEAN13 = CHR(Cod[1, 1] + 35)
strEAN13 = CLIP(strEAN13) & CHR(33)
LOOP i = 2 TO 7
strEAN13 = CLIP(strEAN13) & CHR(Cod[i, 1] + Cod[i, 2])
END
strEAN13 = CLIP(strEAN13) & CHR(45)
LOOP i = 8 TO 13
strEAN13 = CLIP(strEAN13) & CHR(Cod[i, 1] + c)
END
strEAN13 = CLIP(strEAN13) & CHR(33)
RETURN strEAN13
Помогите пожалуйста.
Суть проблемы:
Нужно сгенерировать штрихкод и сохранить его в картинку. В идеале в JPG.
Нужен именно формат EAN-13 из 13 цифр.
Причем хотелось бы не использовать шрифт ean13.ttf. Или как то использовать его без установки в операционную систему. Т.к. нет прав доступа.
Нашел в интернете несколько рабочих вариантов, но они все генерируют только из 12 символьного ШК, а нужно именно 13.
Вот например один из них. Все файлы с UDF во вложении.
; TTF fonts must be installed in system first
#AutoIt3Wrapper_run_obfuscator=y
#Obfuscator_parameters=/so
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <print.au3>
#include <barcode.au3>
$barcode_test = GUICreate("BarCode Test", 601, 174, -1, -1)
GUICtrlCreateLabel("Input:", 11, 10, 30, 17)
$Input = GUICtrlCreateInput("", 41, 8, 120, 21)
GUICtrlCreateLabel("Output:", 171, 10, 38, 17)
$Output = GUICtrlCreateInput("", 209, 8, 120, 21)
GUICtrlSetState(-1, $GUI_DISABLE)
$print = GUICtrlCreateButton("Print", 340, 7, 39, 23)
GUICtrlCreateLabel("Type:", 387, 10, 28, 17)
$type = GUICtrlCreateCombo("", 417, 8, 91, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "Code 128|EAN 8|EAN 13|Code 2 of 5 i|Code 3 of 9", "Code 128")
GUICtrlCreateLabel("Size:", 517, 10, 25, 17)
$size = GUICtrlCreateCombo("", 543, 8, 47, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL))
GUICtrlSetData(-1, "12|18|24|36|48|60|72", "48")
$barcode = GUICtrlCreateLabel("", 10, 39, 580, 130)
GUICtrlSetFont(-1, 48, 400, 0, "Code 128")
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $type
ChangeFont()
ApplyBarcode()
Case $size
ChangeFont()
Case $print
Print()
EndSwitch
WEnd
Func WM_COMMAND($hWinHandle, $iMsg, $wParam, $lParam)
If _WinAPI_HiWord($wParam) = $EN_CHANGE And _WinAPI_LoWord($wParam) = $Input Then
ApplyBarcode()
EndIf
EndFunc
Func ChangeFont()
Switch GUICtrlRead($type)
Case 'Code 128'
$font_name = 'Code 128'
Case 'EAN 8','EAN 13'
$font_name = 'Code EAN13'
Case 'Code 2 of 5 i'
$font_name = 'Code 2 of 5 interleaved'
Case 'Code 3 of 9'
$font_name = 'Code 3 de 9'
EndSwitch
GUICtrlSetFont($barcode, GUICtrlRead($size), 400, 0, $font_name)
EndFunc
Func ApplyBarcode()
Switch GUICtrlRead($type)
Case 'Code 128'
$barcode_data = barcode_128(GUICtrlRead($Input))
Case 'EAN 8'
$barcode_data = barcode_ean8(GUICtrlRead($Input))
Case 'EAN 13'
$barcode_data = barcode_ean13(GUICtrlRead($Input))
Case 'Code 2 of 5 i'
$barcode_data = barcode_25i(GUICtrlRead($Input))
Case 'Code 3 of 9'
$barcode_data = barcode_39(GUICtrlRead($Input))
EndSwitch
GUICtrlSetData($Output, $barcode_data)
GUICtrlSetData($barcode, $barcode_data)
EndFunc
; print given text on default printer in given size by all available barcode types
Func Print()
$sPrinter = _GetDefaultPrinter()
If $sPrinter = "" Then Return
$hPrintDC = _WinAPI_CreateDC("winspool", $sPrinter)
_InitPrinter($hPrintDC, "Printing Barcodes from AutoIt") ; print job name
$hFont = _CreateFont_Simple('Arial', 12, $FW_BOLD)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 500, 'Input data: ' & GUICtrlRead($Input), 0xFF0000)
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Courier', 10, $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_WinAPI_SetTextColor($hPrintDC, 0x000000)
_TextOut_Centered($hPrintDC, 1400, 'Code 128')
_TextOut_Centered($hPrintDC, 2400, 'EAN 8')
_TextOut_Centered($hPrintDC, 3400, 'EAN 13')
_TextOut_Centered($hPrintDC, 4400, 'Code 2 of 5 i')
_TextOut_Centered($hPrintDC, 5400, 'Code 3 of 9')
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code 128', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 1500, barcode_128(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code EAN13', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 2500, barcode_ean8(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code EAN13', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 3500, barcode_ean13(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code 2 of 5 interleaved', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 4500, barcode_25i(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
$hFont = _CreateFont_Simple('Code 3 de 9', GUICtrlRead($size), $FW_NORMAL)
$hFontOld = _WinAPI_SelectObject($hPrintDC, $hFont)
_TextOut_Centered($hPrintDC, 5500, barcode_39(GUICtrlRead($Input)))
_WinAPI_SelectObject($hPrintDC, $hFontOld)
_WinAPI_DeleteObject($hFont)
_DeInitPrinter($hPrintDC)
EndFunc
Вот еще нашел решение, но непонятно на каком языке. Может будет полезно:
PROGRAM
MAP
MODULE('Windows API')
AddFontResource(*CSTRING FontName),RAW,LONG,PASCAL,NAME('AddFontResourceA')
END
EAN13(STRING Barcode), STRING
END
LOC:FontFileName CSTRING(20)
LOC:Barcode1 CSTRING(20)
LOC:Barcode2 CSTRING(20)
LOC:Barcode3 CSTRING(20)
Window WINDOW('Use EAN13 Font'),AT(,,161,140),FONT('MS Sans Serif',8,,FONT:regular),CENTER,GRAY,DOUBLE
STRING(@s20),AT(18,9),USE(LOC:Barcode1)
STRING(@s20),AT(18,48),USE(LOC:Barcode2)
STRING(@s20),AT(18,97),USE(LOC:Barcode3)
END
CODE
LOC:FontFileName = 'EANG000.TTF'
IF NOT AddFontResource(LOC:FontFileName)
MESSAGE('Error on load: ' & LOC:FontFileName,'Warning',ICON:Hand)
END
OPEN(Window)
?LOC:Barcode1{PROP:Font} = 'EanGnivc'
?LOC:Barcode1{PROP:FontSize} = 20
?LOC:Barcode2{PROP:Font} = 'EanGnivc'
?LOC:Barcode2{PROP:FontSize} = 30
?LOC:Barcode3{PROP:Font} = 'EanGnivc'
?LOC:Barcode3{PROP:FontSize} = 40
LOC:Barcode1 = EAN13(2340600973341)
LOC:Barcode2 = EAN13(6945198851772)
LOC:Barcode3 = EAN13(2901214010046)
ACCEPT
END
CLOSE(Window)
EAN13 FUNCTION(STRING Barcode)!, STRING
a LONG(48)
b LONG(65)
c LONG(97)
d LONG(35)
i LONG
Cod LONG,DIM(13,2)
f LONG,DIM(6,10)
strEAN13 STRING(20)
CODE
IF LEN(CLIP(BarCode)) <> 13
MESSAGE('Штрих код за пределами отведенного диапазона')
RETURN ''
END
f[1,0] = a; f[1,1] = a; f[1,2] = a; f[1,3] = a; f[1,4] = a
f[1,5] = a; f[1,6] = a; f[1,7] = a; f[1,8] = a; f[1,9] = a
f[2,0] = a; f[2,1] = a; f[2,2] = a; f[2,3] = a; f[2,4] = b
f[2,5] = b; f[2,6] = b; f[2,7] = b; f[2,8] = b; f[2,9] = b
f[3,0] = a; f[3,1] = b; f[3,2] = b; f[3,3] = b; f[3,4] = a
f[3,5] = b; f[3,6] = b; f[3,7] = a; f[3,8] = a; f[3,9] = b
f[4,0] = a; f[4,1] = a; f[4,2] = b; f[4,3] = b; f[4,4] = a
f[4,5] = a; f[4,6] = b; f[4,7] = b; f[4,8] = b; f[4,9] = a
f[5,0] = a; f[5,1] = b; f[5,2] = a; f[5,3] = b; f[5,4] = b
f[5,5] = a; f[5,6] = a; f[5,7] = a; f[5,8] = b; f[5,9] = b
f[6,0] = a; f[6,1] = b; f[6,2] = b; f[6,3] = a; f[6,4] = b
f[6,5] = b; f[6,6] = a; f[6,7] = b; f[6,8] = a; f[6,9] = a
LOOP i = 1 TO 13
Cod[i, 1] = SUB(BarCode, i, 1)
END
LOOP i = 2 TO 7
Cod[i, 2] = f[i - 1, Cod[1, 1]]
END
strEAN13 = CHR(Cod[1, 1] + 35)
strEAN13 = CLIP(strEAN13) & CHR(33)
LOOP i = 2 TO 7
strEAN13 = CLIP(strEAN13) & CHR(Cod[i, 1] + Cod[i, 2])
END
strEAN13 = CLIP(strEAN13) & CHR(45)
LOOP i = 8 TO 13
strEAN13 = CLIP(strEAN13) & CHR(Cod[i, 1] + c)
END
strEAN13 = CLIP(strEAN13) & CHR(33)
RETURN strEAN13
Помогите пожалуйста.