C#控制DataMax打印机问题总结
最近兩周時間一直在測試系統涉及條碼打印問題,由于原來系統采用通用驅動方式統一Intermac/ZeBar/DataMAx打印.但在處理DataMax打印效果是出現打印條碼出現鋸齒散射狀,導致掃描槍無法識別.
我拿到打印機型號DataMax-I-4208熱敏打印型號,坦白說解決問題過程是很折磨人的,一方面源自這方面官方提供資源和打印實例有限,另外一方面設計到設備參數具體調試, 針對C#控制DataMax-I-4208一系列問題解決方法作如下總結:
<1>DataMax打印Code128條碼出現鋸齒狀
首先要明白一個概念:DPI [Dots Per Inch]的縮寫。每英寸所打印的點數或線數,用來表示打印機打印分辨率。dpi是指單位面積內像素的多少,也就是掃描精度,目前國際上都是計算一平方英寸面積內像素的多少。dpi越小,掃描的清晰度越低.
DataMax打印機型號:DataMax-I-4208-203DPI
當我們在默認情況下把系統生成的條碼BMP格式圖片通過驅動方式發給打印機.采用DPI是當前本地系統屏幕默認顯示的DPI值一般是96DPI. 這樣導致打印機值不一致出現就 鋸齒 模糊打印效果: C#中如何設置修改DPI:
1: //設置DPI決定屬性值與DataMAx必須相符203DPI 必須一致
2: var setdpiimg = (Bitmap)_DrawImg;
3: if (setdpiimg != null)
4: {
5: setdpiimg.SetResolution(203f, 203f);
6: }
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
DPI是每英寸點數, 如果DPI的值過低,則圖片在每英寸點數較少 位圖打印后效果則比較模糊. 設置DPI值變大后圖片則明顯變小,清晰度變高,發現打印條碼掃描槍能識別,至于大小可以通過移位替換方式高質量縮放的進行轉換:C#控制代碼
1: //縮放控制[高質量]
2: Bitmap getbitmap = new Bitmap(300,400);
3: Graphics newgra = Graphics.FromImage(getbitmap);
4:
5: //插值算法質量控制
6: newgra.InterpolationMode = InterpolationMode.HighQualityBicubic;
7: newgra.DrawImage(DrawImg,new Rectangle(0,0,DrawImg.Width,DrawImg.Height),
8: new Rectangle(0,0,getbitmap.Width,getbitmap.Height),GraphicsUnit.Pixel);
9: newgra.Dispose();
10:
11: return getbitmap;
如上控制圖片大小設置Width:300PX[像素] Height:400PX[像素] 可以自定義設置.
C#進行打印輸出控制后基本能夠完整打印: 效果:
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
打印基本OK.
<2>DataMax-I-4208 DPL指令方式打印
當我們通過程序通用驅動方式去打印,發送給打印機是一張位圖Bitmap圖片,輸出打印. DataMax DPL方式則更直接通過指令編碼實現對條碼打印精確控制. DPL編程時DAtaMax定義一套打印指令 完全不同InterMac和Zebar[斑馬]打印機. 如何獲得DPL Program HandleBook 編程手冊:
首先找到驅動盤,讀取驅動內容發現:
運行Do應用程序:
找到指定打印機類型: Data Max-I系列 即I-Class:
找到開發人員手冊PDF:
紅色標識是驅動程序, 綠色標識就是我們需要的Programmer HandleBook 開發人員手冊即DPL指令集如果你沒有驅動盤則可以如下鏈接方式下載DPL完整指令集:
DataMax-I-Class DPI指令集PDF下載
原始的DPL 指令集是全英的,總頁數多大350多頁, 我個人經驗是 針對這個DPL Programmer PDF 文檔不要過于盲目的去查看, 主要是因為內容太多,而且大多數你都用不到, 所以在看這份文檔前 仔細的閱讀以下目錄會很容易找到你想要東西, .這點會讓你事半功力倍:
在DPL手冊查找指令前 要知道我們我們需要指令控制什么因素: 針對BarCode Code 128格式做了大概分析影響因素如下:
<1>Print Speed打印速度[如果不是特別快或特別慢采用默認]
<2>Label Location 條碼坐標位置
<3>Chinese Control 中文字符處理 –默認情況打印中文是出現亂碼 ??? 需要額外配置
<4>Label Value 條碼值
<5>Label Frmat 條碼打印格式
既然有了需求 剩下工作也是不斷查找打印指令 測試輸出效果一個過程: 現在我們打印一個最為基本字符串大概來看一下DPL 指令格式 :
1: //打印一個字符串DPL指令
2: <STX>L
3: D11<CR>
4: 1T0000000150100ABCDEF<CR>
5: 121100000000100Barcode T<CR>
6: E
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }DPL文檔并沒有對打印指令的語法格式進行說明,大多在說如何去設置 采用什么樣指令, 說以在大概無數次測試中我也大概掌握DPL打印指令的基本語法格式 分享給各位[可能不準確]:
<STX>L:指定的是打印類型 <STX>L 自定打印一個條碼
Dll:則是對打印類型下更一步細分類似條碼 則分為Code 128 UPC-E 或二維碼等
<CR>: 類似C#每行代碼的; 指定當前本行指令結束符
E: 則是指定整段指令結束符 也就是說E 字符后面打印機自動不讀取識別的.
通過串口發送給打印機 指令完全正確 但DataMax-i-4208完全沒有反映,后來我聯系廠商才明白:
<STX>打印指令頭需要需要轉換16進制打印機才能識別 轉換后在TXT文本效果:
ok.通過串口工具發送指令給打印機 DataMax-i-4208終于開始響應 打印效果:
打印成功 DPL指令方式唯一不用擔憂的條形碼的質量 很清晰,指令這種模式做一個簡單類比 打印機就類似一個ATM取款機,不同的人攜帶不同的銀行卡即對應不同DPL 打印指令就能取到不同貨幣美元 RMB等即對應打印結果.
而驅動方式 則前提是必須通過程序方式生成一張完整清晰的圖片, 數據發送給打印機 打印采用自己設置和字庫進行畫出來打印.
那么測試指令沒有問題如何通過C#編程方式發給打印機,再來看如何在編程中控制條碼的位置:
條碼打印在打印紙都有一個坐標位置對應X /y 很多人對于DPL指令如何條碼位置都很迷茫, 經過多方驗證得多結論 DPL設置:
Row OffSet 設置對應行起始位置就X坐標位置
Column Offset 設置對飲列起始坐標位置 即Y坐標位置
還有兩個參數:
ROW ADJUST(行調整) 以點為單位對行起始位置(ROW OFFSET)進行微調
COLUMN ADJUST(列調整) 以點為單位對列起始位置(COLUMN OFFSET)進行微調
現在有了DPL參數名稱 我要告訴你不要就直接跑到 DPL 350頁大文檔里去一點點去翻 給你一個直接簡單方式 利用PDF的查找快速定位你要找內容 雖然覺得這沒什么 可是我要告訴你這種簡單效果 在一個非母語的文檔 效果還是非常好的:
詳細語法說明:
其他設置基本雷同,那么在C#編程的話就要DPL指令格式限制問題. 類似我們制定X坐標即Row Offset的值 語法是R0037<CR>結束.首先X坐標的值范圍是0-9999,而且DPL規定格式必須是4位數. 也就是說類似設置X坐標為5 DPL標準識別格式:R0005<CR> C#進行控制:
1: /// <summary>
2: /// 處理數據寬高格式0000 打印指令0010
3: /// </summary>
4: public string ConvertDataFormat(float getvalue)
5: {
6: string converstr = string.Empty;
7: if (!string.IsNullOrEmpty(getvalue.ToString()))
8: {
9: //Convert Float to int type
10: string getfromtint = Convert.ToInt32(getvalue.ToString()).ToString();
11: if (4 - getfromtint.Length > 0)
12: {
13: for (int count = 0; count < 4 - getfromtint.Length; count++)
14: {
15: getfromtint = "0" + getfromtint;
16: }
17: converstr = getfromtint;
18: }
19: else
20: {
21: //長度超過或等于格式長度4
22: if (4 - getfromtint.Length == 0)
23: converstr = getfromtint;
24: else
25: {
26: converstr = string.Empty;
27: throw new EquipmentException("設定打印元素初始打印位置超過本地打印機設置 設置小于等于4位數");
28: }
29: }
30: }
31: return converstr;
32: }
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
針對<STX>打印標頭轉換 16進制控制:
1: /// <summary>
2: /// Start Print CodeChar 指令:"<STX>L"
3: /// 轉換成16進制AS#格式
4: /// </summary>
5: protected override string Leading()
6: {
7: #region 轉16進制數據
8: byte[] bytes = System.Text.Encoding.Default.GetBytes("<STX>L");
9: string reStr = string.Empty;
10: foreach (byte b in bytes)
11: {
12: short st = (short)(b - '\0');
13: reStr += st.ToString("x") + "%";
14: }
15: #endregion
16: return reStr;
17: }
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
獲取字體方法:
1: //字體設置
2: using System.Runtime.InteropServices;
3: [DllImport("fnthex32.dll", CharSet = CharSet.Ansi)]
4: public static extern int GETFONTHEX(
5: string chnstr,
6: string fontname,
7: int orient,
8: int height,
9: int width,
10: int bold,
11: int italic,
12: StringBuilder cBuf);
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
對于中文字體也就是Chinese Simple[中文簡體格式]是雙字節 在DataMax中, 默認是不支持中文,類似我們把打印指令換成漢字 打印結果是出來字符亂碼 ??? 這是什么問題. 我查了DAtaMAx官方對Chinese simple 中說明發現 如果需要DataMax打印中文則需要安裝字庫或在打印機上安裝中文字卡才能識別. 如果不安裝字卡 還有另外一種方式 采用第三方控件方式支持中文打印:
標準控件:http://www.51barcode.com/downloads/list.asp?id=82 或者可通過第三方條碼軟件控件實現如Codesoft等
C#識別中文字符判斷:
2: /// 驗證是否是中文字符
4: public bool IsChinese(string getvalue)
5: {
6: return System.Text.RegularExpressions.Regex.IsMatch(getvalue, @"[\u4e00-\u9fa5]");
7: }
DPL手冊中對Chinese Simple中文簡體打印方式做了詳細說明 詳見DPL PDF文檔手冊285/250/254頁:
針對DataMax中文打印問題 DPL手冊中給了一個打印漢字 盒 的例子 可惜這個例子 我經過N多次嘗試 通過串口發送打印DPL 始終沒能成功使用這個例子. 后來詳細研究這個DPL 文件.發現針對中文設置的語法其實很簡單:
1: //打印漢字DPL語法
2: <STX>L<CR>
3: D11<CR>
4: ySPM<CR>
5: 1911S0003100010P020P015 Chinese Available in GB r Set<CR>
6: yUGB<CR>
7: 1911UC001200145P040P030<BA><D0><00><00><CR>
8: 1911UC001200190P040P040<BA><D0><00><00><CR>
9: 1911UC001200250P040P050<BA><D0><00><00><CR>
10: 1911UC001200320P040P060<BA><D0><00><00><CR>
11: E
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
ySPM<CR>是打印語言和字體支持設置語法. ySPM是默認設置, yUGB則對應打印中文字體 這個設置很重要. 那么我發現在DPL中并沒有漢字,其實DAtaMax針對打印漢字支持格式是GBK格式編碼 類似我們現在看到 漢字 盒 對應編碼就是<BA><DO><OO><OO>. C#中默認字符UNICODE格式這個得注意 需要把漢字重新轉碼在傳入DPL指令中 打印機才能識別. 打印出來結果是 4個盒字:
在來說打印條碼Code128格式 DPL指令:
1: //打印Code 128
2: <STX>L
3: D11<CR>
4: 1E000000015010001234567890<CR>
5: 121100000000100Barcode E<CR>
6: E
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, "Courier New", courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
輸出效果:
總結
以上是生活随笔為你收集整理的C#控制DataMax打印机问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Google谷歌搜索引擎镜像入口网址大全
- 下一篇: AutoCAD 2008如何绘制环形弹簧