最近試著在 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) 之後, 就可以正常處理中文了.
Tommy大大您好!
小弟我日前執行了上述程式碼
執行到FSymbol.symbology := BARCODE_QRCODE;這行時會發生錯誤
想冒昧請問一下大大為什麼?謝謝!
(小弟的程式環境為:Delphi7)
我把那些常數放在另一個檔案內了.
你可以自行定義那些常數或直接把 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;
謝謝大大無私的教導!!
感激不盡!!
版主你好
冒昧請問為什麼用手機讀取中文編成的QR code會變成亂碼?
(不好意思!!因為最後一段看不懂才提問~麻煩你了)
中文亂碼的問題, 你有把 input_mode 改成 0 (DATA_MODE) 嗎? 如果用 UNICODE_MODE 反而會是亂碼.
恩...應該說我沒看到程式碼的input_mode有哪裡可以改成0?
我是用版主您寫的程式碼,不是用那個網站裡的單元.
麻煩你了!!謝謝!!
PS.不好意思,因為我是程式新手,所以如果是我眼殘沒看到在哪改,那我先說聲抱歉!!
FSymbol.symbology := BARCODE_QRCODE;
前面加上
FSymbol.input_mode := 0;
試看看.
版主你好
上述方法我在發問前已經有自己先試過,
可是中文還是一樣是亂碼,
不知道版主那邊是不是把mode設為0就ok了?
因為我這邊不管是設為0還是1.2.3.4都是亂碼
我自己試是用 big5 或 utf8 都可以看到 (QRCode 本來就有支援這兩種).
http://www.teatime.com.tw/~tommy/files/zint_d5_example.7z
上頭是我在 Delphi5 上頭用的例子.
那我在試試看好了!
總之謝謝版主不厭其煩的回覆!
感謝您!!
请问版主,如何调整QRcode的宽度和高度
把圖放到 image 之類的元件裡頭, 自己要拉成多大就拉多大.
你好,zintinterface生成的qrcode与google在线生成的区别还是比较大,请问这是什么原因造成的,谢谢!
也許是不同的內碼吧.
谢谢,^_^
你好,我已经试验通过了,只是在FastReport中 二维码 高、宽无法调整,固定1.11 , 改如何做呢,放大缩小
楼主你好,很佩服你的技术水平。
能否给出你的电邮或者联系方式。
我现在遇到一个比较棘手的问题:
1、就是上面说说的, 在FastReport中 二维码 高、宽无法调整。
2、用ZATO条码打印机打印 二维码的时候,我以前是用的BMP位图转换就是 保持到文件然后调用文件,再用FastReport打印,但这有个问题就是 条码打印机打印位图会出现背影,不清晰,印象扫描效果。
不知道 你的这种方法里面会不会有这种现象。
我的邮箱:[email protected]
QQ: 12507070
期待与您的交流,谢谢。
我沒用 fastreport, 不過在 quickreport (Delphi 5) 裡頭 (直接產生圖形的 buffer 給 QRImage 裡頭的 Picture.Bitmap 物件) 或者是寫成 DLL 產生 .bmp 檔案給別的程式用, 都沒有你說的問題.
對了, 如果要 email 的話, 這個網頁的右上方應該有個連結可以用.
谢谢,我自己解决了。这是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系统要报错。
zint 在 windows 下是用 vc2008 編譯的, 所以都會需要 vc2008 的 vcredist_x86.exe (不管用那一個 windows 版本都要, 不需要的有可能是之前就有裝過了)
ZBarcodeToBitmap(FSymbol, Image1.Picture.Bitmap);
编译不了,提示如下
E2010 Incompatible types: 'uBitMapOverriden.TBitmap' and 'Graphics.TBitmap'
高手 謝謝你 真的行 我在delphi5成功了
我是成功了,在測試的時候,數值英文網頁都可以,唯獨繁體中文,scan出來,出現日文字.高手大大為何會這樣,求解
上面有人提到如何放大倍数,其实很简单,我根据源码得出答案:FSymbol.scale := x;x为任意整数值
感恩~真的可以,
但我想問一下,如果我不需要顯示條碼文字該如何呢?
我是D7~
我猜是這個參數吧:
show_human_readable_text
感謝版主熱心提供重要的引用PAS檔。我使用Delphi 7在Windows 7環境中編譯執行,可輸入中文,可產生QR-Code,但卻無法被正確解析出來,就算input_mode := 0還是無解。後來又爬了其他不相干文章,發現了一個簡單解決中文的方式:
把字串轉呈UTF8後再產生QR-COde
s := UTF8Encode(Memo1.Text);
請問怎麼設定QRCODE的容錯率與VERSION呢?謝謝您囉
請問不顯下方文字是加在ZintInterface.pas程式碼內??
測試 ASymbol.show_human_readable_text:=0或1;->都沒用.
請問該如何使用?謝謝~~
請問應如何改變條碼下方文字大小?謝謝~~
show_human_readable_text 不是所有的 barcode 都支援.
文字大小應該沒辦法調整.
有問題可以到 https://github.com/zint/zint 去反應.
感謝版大的分享
但是我在delphi7上
只要跑到ABitmap.Height := ASymbol.bitmap_height;
系統就會出現
"out of system resources" 錯誤訊息,
根本執行不了,
請問版大應從那個著手呢?謝謝!
樓上"out of system resources"的問題,到
https://github.com/chaosben/theunknownones/tree/master/Components/ZintBarcode
下載zint.dll來用就可以。
感謝版主的分享,最近客戶要求,以前都用TSC條碼標籤機直接搞定,這次要求用一般A4雷射印表機印出來,想說完蛋了,還好扒到這裏來一次搞定客戶的需求!感謝~
對了,要順便感謝Sam Huang,
分享zint.dll的連結,一開始用更新的zint.dll也是一樣出現"out of system resources",還好您有分享另外一個zint.dll連結~哈,雖然你是一年前留言的,不過,一年後救了我!讚~
上星期,客人要求用CODE128,還好這個也有支援,又再次救了我一次,要不然CODE128要用字型檔加上程式處理,其實也蠻複雜的.