Tommy 碎碎念

Tommy Wu's blog

« 上一篇 | 下一篇 »

Zint Barcode Generator
post by tommy @ 02 三月, 2012 09:57

最近試著在 Delphi 中產生 QR-Code, 找到了 zint 這東西, 也找到有人針對 zint.dll 做的 Delphi  模組. 不過... 適用的 Delphi 版本是在 D10 之後, 我們用的 D3 與 D5 (沒錯了, 很老了) 都無法直接用.由於我們的需求很簡單, 所以放棄那個 uZintBarcode.pas 模組, 直接改 uZintInterface.pas 來用 (這個 DLL 的 import 用法, 在 Delphi 的版本之間差異不大, 改幾個地方就能用了.

unit ZintInterface;
 
interface
 
{$M+}
 
uses Windows, Classes, SysUtils, Graphics, Dialogs;
 
type
TZSymbol = record
symbology: Integer;
height: Integer;
whitespace_width: Integer;
border_width: Integer;
output_options: Integer;
fgcolour: array[0..9] of AnsiChar;
bgcolour: array[0..9] of AnsiChar;
outfile: array [0..255] of AnsiChar;
scale: double;
option_1: Integer;
option_2: Integer;
option_3: Integer;
show_human_readable_text: Integer;
input_mode: Integer;
text: array[0..127] of AnsiChar;
rows: Integer;
width: Integer;
primary: array [0..127] of AnsiChar;
encoded_data: array[0..177] of array[0..177] of AnsiChar;
row_height: array[0..177] of Integer;
errtxt: array[0..99] of AnsiChar;
bitmap: PAnsiChar;
bitmap_width: Integer;
bitmap_height: Integer;
rendered: Pointer;
end;
PZSymbol = ^TZSymbol;
 
const
LibName = 'zint.dll';
 
function ZBarcode_Create: PZSymbol; cdecl; external LibName;
procedure ZBarcode_Delete(symbol: PZSymbol); cdecl; external LibName;
procedure ZBarcode_Clear(symbol: PZSymbol); cdecl; external LibName;
function ZBarcode_Buffer(symbol: PZSymbol; rotate_angle: Integer): Integer; cdecl; external LibName;
function ZBarcode_Encode_and_Buffer(symbol: PZSymbol; input: PAnsiChar; length: Integer; rotate_angle: Integer): Integer; cdecl; external LibName;
 
procedure ZBarcodeToBitmap(ASymbol: PZSymbol; const ABitmap: TBitmap);
 
implementation
 
procedure ZBarcodeToBitmap(ASymbol: PZSymbol; const ABitmap: TBitmap);
var myp: PRGBTriple;
row: Integer;
rowwidth: Integer;
begin
ABitmap.PixelFormat := pf24bit;
ABitmap.Width := ASymbol.bitmap_width;
ABitmap.Height := ASymbol.bitmap_height;
 
myp := Pointer(ASymbol.bitmap);
rowwidth := Asymbol.bitmap_width * 3;
 
for row := 0 to ASymbol.bitmap_height - 1 do
begin
CopyMemory(ABitmap.ScanLine[row], myp, rowwidth);
Inc(myp, Asymbol.bitmap_width);
end;
end;
 
end.

使用上也很簡單:

procedure TForm1.Button1Click(Sender: TObject);
var FSymbol: PZSymbol;
s: string;
begin
Image1.Picture.Bitmap := nil;
s := Memo1.Text;
FSymbol := ZBarcode_Create;
try
FSymbol.symbology := BARCODE_QRCODE;
ZBarcode_Encode_and_Buffer(FSymbol, PChar(s), Length(s), 0);
ZBarcodeToBitmap(FSymbol, Image1.Picture.Bitmap);
finally
ZBarcode_Delete(FSymbol);
FSymbol := nil;
end;
end;

對於中文 (Big5 或 UTF-8) 也能正常的處理.

PS. 如果你是使用比較高的 Delphi 版本, 可以直接使用那個 uZintBarcode.pas 模組... 不過要注意的是, 裡頭會把 input_mode 設為 UNICODE_MODE (1), 這個名稱看起來是要能處理 Unicode,不過... 用了這一個 mode, 反而會造成中文變成亂碼 (不管 Big5 或 UTF-8 都一樣), 害我測了很久都找不出為什麼不能用中文. 後來看了 source code, 發現這個處理, 只是用來把 latin 的符號轉成 unicode (基本上, 與非英文語系的 unicode 完全沒關係), 改成 DATA_MODE (0) 之後, 就可以正常處理中文了.

Del.icio.us Furl HEMiDEMi Technorati MyShare
commons icon [1] Re:Zint Barcode Generator [ 回覆 ]

Tommy大大您好!
小弟我日前執行了上述程式碼
執行到FSymbol.symbology := BARCODE_QRCODE;這行時會發生錯誤
想冒昧請問一下大大為什麼?謝謝!
(小弟的程式環境為:Delphi7)

commons icon [2] Re:Zint Barcode Generator [ 回覆 ]

我把那些常數放在另一個檔案內了.
你可以自行定義那些常數或直接把 BARCODE_QRCODE 改成 58.

const
{ Tbarcode 7 codes }
BARCODE_CODE11 = 1;
BARCODE_C25MATRIX = 2;
BARCODE_C25INTER = 3;
BARCODE_C25IATA = 4;
BARCODE_C25LOGIC = 6;
BARCODE_C25IND = 7;
BARCODE_CODE39 = 8;
BARCODE_EXCODE39 = 9;
BARCODE_EANX = 13;
BARCODE_EAN128 = 16;
BARCODE_CODABAR = 18;
BARCODE_CODE128 = 20;
BARCODE_DPLEIT = 21;
BARCODE_DPIDENT = 22;
BARCODE_CODE16K = 23;
BARCODE_CODE49 = 24;
BARCODE_CODE93 = 25;
BARCODE_FLAT = 28;
BARCODE_RSS14 = 29;
BARCODE_RSS_LTD = 30;
BARCODE_RSS_EXP = 31;
BARCODE_TELEPEN = 32;
BARCODE_UPCA = 34;
BARCODE_UPCE = 37;
BARCODE_POSTNET = 40;
BARCODE_MSI_PLESSEY = 47;
BARCODE_FIM = 49;
BARCODE_LOGMARS = 50;
BARCODE_PHARMA = 51;
BARCODE_PZN = 52;
BARCODE_PHARMA_TWO = 53;
BARCODE_PDF417 = 55;
BARCODE_PDF417TRUNC = 56;
BARCODE_MAXICODE = 57;
BARCODE_QRCODE = 58;
BARCODE_CODE128B = 60;
BARCODE_AUSPOST = 63;
BARCODE_AUSREPLY = 66;
BARCODE_AUSROUTE = 67;
BARCODE_AUSREDIRECT = 68;
BARCODE_ISBNX = 69;
BARCODE_RM4SCC = 70;
BARCODE_DATAMATRIX = 71;
BARCODE_EAN14 = 72;
BARCODE_CODABLOCKF = 74;
BARCODE_NVE18 = 75;
BARCODE_JAPANPOST = 76;
BARCODE_KOREAPOST = 77;
BARCODE_RSS14STACK = 79;
BARCODE_RSS14STACK_OMNI = 80;
BARCODE_RSS_EXPSTACK = 81;
BARCODE_PLANET = 82;
BARCODE_MICROPDF417 = 84;
BARCODE_ONECODE = 85;
BARCODE_PLESSEY = 86;

{ Tbarcode 8 codes }
BARCODE_TELEPEN_NUM = 87;
BARCODE_ITF14 = 89;
BARCODE_KIX = 90;
BARCODE_AZTEC = 92;
BARCODE_DAFT = 93;
BARCODE_MICROQR = 97;

{ Tbarcode 9 codes }
BARCODE_HIBC_128 = 98;
BARCODE_HIBC_39 = 99;
BARCODE_HIBC_DM = 102;
BARCODE_HIBC_QR = 104;
BARCODE_HIBC_PDF = 106;
BARCODE_HIBC_MICPDF = 108;
BARCODE_HIBC_BLOCKF = 110;
BARCODE_HIBC_AZTEC = 112;

{ Zint specific }
BARCODE_AZRUNE = 128;
BARCODE_CODE32 = 129;
BARCODE_EANX_CC = 130;
BARCODE_EAN128_CC = 131;
BARCODE_RSS14_CC = 132;
BARCODE_RSS_LTD_CC = 133;
BARCODE_RSS_EXP_CC = 134;
BARCODE_UPCA_CC = 135;
BARCODE_UPCE_CC = 136;
BARCODE_RSS14STACK_CC = 137;
BARCODE_RSS14_OMNI_CC = 138;
BARCODE_RSS_EXPSTACK_CC = 139;
BARCODE_CHANNEL = 140;
BARCODE_CODEONE = 141;
BARCODE_GRIDMATRIX = 142;

commons icon [3] Re:Zint Barcode Generator [ 回覆 ]

謝謝大大無私的教導!!
感激不盡!!

commons icon [4] Re:Zint Barcode Generator [ 回覆 ]

版主你好
冒昧請問為什麼用手機讀取中文編成的QR code會變成亂碼?
(不好意思!!因為最後一段看不懂才提問~麻煩你了)

commons icon [5] Re:Zint Barcode Generator [ 回覆 ]

中文亂碼的問題, 你有把 input_mode 改成 0 (DATA_MODE) 嗎? 如果用 UNICODE_MODE 反而會是亂碼.

commons icon [6] Re:Zint Barcode Generator [ 回覆 ]

恩...應該說我沒看到程式碼的input_mode有哪裡可以改成0?
我是用版主您寫的程式碼,不是用那個網站裡的單元.
麻煩你了!!謝謝!!

PS.不好意思,因為我是程式新手,所以如果是我眼殘沒看到在哪改,那我先說聲抱歉!!

commons icon [7] Re:Zint Barcode Generator [ 回覆 ]

FSymbol.symbology := BARCODE_QRCODE;
前面加上
FSymbol.input_mode := 0;
試看看.

commons icon [8] Re:Zint Barcode Generator [ 回覆 ]

版主你好
上述方法我在發問前已經有自己先試過,
可是中文還是一樣是亂碼,
不知道版主那邊是不是把mode設為0就ok了?

因為我這邊不管是設為0還是1.2.3.4都是亂碼

commons icon [9] Re:Zint Barcode Generator [ 回覆 ]

我自己試是用 big5 或 utf8 都可以看到 (QRCode 本來就有支援這兩種).
http://www.teatime.com.tw/~tommy/files/zint_d5_example.7z
上頭是我在 Delphi5 上頭用的例子.

commons icon [10] Re:Zint Barcode Generator [ 回覆 ]

那我在試試看好了!
總之謝謝版主不厭其煩的回覆!
感謝您!!

commons icon [11] Re:Zint Barcode Generator [ 回覆 ]

请问版主,如何调整QRcode的宽度和高度

commons icon [12] Re:Zint Barcode Generator [ 回覆 ]

把圖放到 image 之類的元件裡頭, 自己要拉成多大就拉多大.

commons icon [13] Re:Zint Barcode Generator [ 回覆 ]

你好,zintinterface生成的qrcode与google在线生成的区别还是比较大,请问这是什么原因造成的,谢谢!

commons icon [14] Re:Zint Barcode Generator [ 回覆 ]

也許是不同的內碼吧.

commons icon [15] Re:Zint Barcode Generator [ 回覆 ]

谢谢,^_^

commons icon [16] Re:Zint Barcode Generator [ 回覆 ]

你好,我已经试验通过了,只是在FastReport中 二维码 高、宽无法调整,固定1.11 , 改如何做呢,放大缩小

commons icon [17] Re:Zint Barcode Generator [ 回覆 ]

楼主你好,很佩服你的技术水平。
能否给出你的电邮或者联系方式。
我现在遇到一个比较棘手的问题:

1、就是上面说说的, 在FastReport中 二维码 高、宽无法调整。

2、用ZATO条码打印机打印 二维码的时候,我以前是用的BMP位图转换就是 保持到文件然后调用文件,再用FastReport打印,但这有个问题就是 条码打印机打印位图会出现背影,不清晰,印象扫描效果。
不知道 你的这种方法里面会不会有这种现象。

我的邮箱:fsse2000@163.com
QQ: 12507070

期待与您的交流,谢谢。

commons icon [18] Re:Zint Barcode Generator [ 回覆 ]

我沒用 fastreport, 不過在 quickreport (Delphi 5) 裡頭 (直接產生圖形的 buffer 給 QRImage 裡頭的 Picture.Bitmap 物件) 或者是寫成 DLL 產生 .bmp 檔案給別的程式用, 都沒有你說的問題.

commons icon [19] Re:Zint Barcode Generator [ 回覆 ]

對了, 如果要 email 的話, 這個網頁的右上方應該有個連結可以用.

commons icon [20] Re:Zint Barcode Generator [ 回覆 ]

谢谢,我自己解决了。这是FastReport中的。
1、在FastReport中有个 AutoSize 属性, 默认不勾即可。

2、在预览关闭之后,画的二维码,比如是 5cm×5cm,已关闭打印预览,二维码又变成了 1.11×1.11,
结果我修改了里面的源码:
屏蔽 self.height:= ***
self.width:= ***
就可以了。

3、在这个Zint.DLL调用的时候,XP环境下,需要打个补丁
VC++ 2008 (vcredist_x86.exe) 补丁。
这估计是调用DLL的环境吧。
不然XP系统要报错。

commons icon [21] Re:Zint Barcode Generator [ 回覆 ]

zint 在 windows 下是用 vc2008 編譯的, 所以都會需要 vc2008 的 vcredist_x86.exe (不管用那一個 windows 版本都要, 不需要的有可能是之前就有裝過了)

commons icon [22] Re:Zint Barcode Generator [ 回覆 ]

ZBarcodeToBitmap(FSymbol, Image1.Picture.Bitmap);
编译不了,提示如下
E2010 Incompatible types: 'uBitMapOverriden.TBitmap' and 'Graphics.TBitmap'

commons icon [23] Re:Zint Barcode Generator [ 回覆 ]

高手 謝謝你 真的行 我在delphi5成功了

commons icon [24] Re:Zint Barcode Generator [ 回覆 ]

我是成功了,在測試的時候,數值英文網頁都可以,唯獨繁體中文,scan出來,出現日文字.高手大大為何會這樣,求解

commons icon [25] Re:Zint Barcode Generator [ 回覆 ]

上面有人提到如何放大倍数,其实很简单,我根据源码得出答案:FSymbol.scale := x;x为任意整数值

commons icon [26] Re:Zint Barcode Generator [ 回覆 ]

感恩~真的可以,
但我想問一下,如果我不需要顯示條碼文字該如何呢?
我是D7~

commons icon [27] Re:Zint Barcode Generator [ 回覆 ]

我猜是這個參數吧:
show_human_readable_text

commons icon [28] Re:Zint Barcode Generator [ 回覆 ]

感謝版主熱心提供重要的引用PAS檔。我使用Delphi 7在Windows 7環境中編譯執行,可輸入中文,可產生QR-Code,但卻無法被正確解析出來,就算input_mode := 0還是無解。後來又爬了其他不相干文章,發現了一個簡單解決中文的方式:
把字串轉呈UTF8後再產生QR-COde
s := UTF8Encode(Memo1.Text);

commons icon [29] Re:Zint Barcode Generator [ 回覆 ]

請問怎麼設定QRCODE的容錯率與VERSION呢?謝謝您囉

commons icon [30] Re:Zint Barcode Generator [ 回覆 ]

請問不顯下方文字是加在ZintInterface.pas程式碼內??

測試 ASymbol.show_human_readable_text:=0或1;->都沒用.

請問該如何使用?謝謝~~

commons icon [31] Re:Zint Barcode Generator [ 回覆 ]

請問應如何改變條碼下方文字大小?謝謝~~

commons icon [32] Re:Zint Barcode Generator [ 回覆 ]

show_human_readable_text 不是所有的 barcode 都支援.
文字大小應該沒辦法調整.

有問題可以到 https://github.com/zint/zint 去反應.

commons icon [33] Re:Zint Barcode Generator [ 回覆 ]

感謝版大的分享
但是我在delphi7上
只要跑到ABitmap.Height := ASymbol.bitmap_height;
系統就會出現
"out of system resources" 錯誤訊息,
根本執行不了,
請問版大應從那個著手呢?謝謝!

commons icon [34] Re:Zint Barcode Generator [ 回覆 ]

樓上"out of system resources"的問題,到
https://github.com/chaosben/theunknownones/tree/master/Components/ZintBarcode
下載zint.dll來用就可以。

迴響
暱稱:
標題:
個人網頁:
電子郵件:
authimage

迴響

  

Bad Behavior 已經阻擋了 233 個過去 7 天試圖闖關的垃圾迴響與引用。
Power by LifeType. Template design by JamesHuang. Valid XHTML and CSS