最近兩周時間一直在測試系統涉及條碼列印問題,由于原來系統采用通用驅動方式統一Intermac/ZeBar/DataMAx列印.但在處理DataMax列印效果是出現列印條碼出現鋸齒散射狀,導緻掃描槍無法識别.
我拿到列印機型号DataMax-I-4208熱敏列印型号,坦白說解決問題過程是很折磨人的,一方面源自這方面官方提供資源和列印執行個體有限,另外一方面設計到裝置參數具體調試, 針對C#控制DataMax-I-4208一系列問題解決方法作如下總結:
<1>DataMax列印Code128條碼出現鋸齒狀
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134210422.jpg"></a>
DataMax列印機型号:DataMax-I-4208-203DPI
當我們在預設情況下把系統生成的條碼BMP格式圖檔通過驅動方式發給列印機.采用DPI是目前本地系統螢幕預設顯示的DPI值一般是96DPI. 這樣導緻列印機值不一緻出現就 鋸齒 模糊列印效果: C#中如何設定修改DPI:
//設定DPI決定屬性值與DataMAx必須相符203DPI 必須一緻
var setdpiimg = (Bitmap)_DrawImg;
if (setdpiimg != null)
{
setdpiimg.SetResolution(203f, 203f);
}
DPI是每英寸點數, 如果DPI的值過低,則圖檔在每英寸點數較少 位圖列印後效果則比較模糊. 設定DPI值變大後圖檔則明顯變小,清晰度變高,發現列印條碼掃描槍能識别,至于大小可以通過移位替換方式高品質縮放的進行轉換:C#控制代碼
//縮放控制[高品質]
Bitmap getbitmap = new Bitmap(300,400);
Graphics newgra = Graphics.FromImage(getbitmap);
//插值算法品質控制
newgra.InterpolationMode = InterpolationMode.HighQualityBicubic;
newgra.DrawImage(DrawImg,new Rectangle(0,0,DrawImg.Width,DrawImg.Height),
new Rectangle(0,0,getbitmap.Width,getbitmap.Height),GraphicsUnit.Pixel);
newgra.Dispose();
return getbitmap;
如上控制圖檔大小設定Width:300PX[像素] Height:400PX[像素] 可以自定義設定.
C#進行列印輸出控制後基本能夠完整列印: 效果:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134450234.gif"></a>
列印基本OK.
<2>DataMax-I-4208 DPL指令方式列印
當我們通過程式通用驅動方式去列印,發送給列印機是一張位圖Bitmap圖檔,輸出列印. DataMax DPL方式則更直接通過指令編碼實作對條碼列印精确控制. DPL程式設計時DAtaMax定義一套列印指令 完全不同InterMac和Zebar[斑馬]列印機. 如何獲得DPL Program HandleBook 程式設計手冊:
首先找到驅動盤,讀取驅動内容發現:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134458522.png"></a>
運作Do應用程式:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134507977.png"></a>
找到指定列印機類型: Data Max-I系列 即I-Class:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134516614.png"></a>
找到開發人員手冊PDF:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134526177.png"></a>
紅色辨別是驅動程式, 綠色辨別就是我們需要的Programmer HandleBook 開發人員手冊即DPL指令集如果你沒有驅動盤則可以如下連結方式下載下傳DPL完整指令集:
<a target="_blank" href="http://download.csdn.net/source/775181">DataMax-I-Class DPI指令集PDF下載下傳</a>
原始的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 指令格式 :
//列印一個字元串DPL指令
<STX>L
D11<CR>
1T0000000150100ABCDEF<CR>
121100000000100Barcode T<CR>
E
DPL文檔并沒有對列印指令的文法格式進行說明,大多在說如何去設定 采用什麼樣指令, 說以在大概無數次測試中我也大概掌握DPL列印指令的基本文法格式 分享給各位[可能不準确]:
<STX>L:指定的是列印類型 <STX>L 自定列印一個條碼
Dll:則是對列印類型下更一步細分類似條碼 則分為Code 128 UPC-E 或二維碼等
<CR>: 類似C#每行代碼的; 指定目前本行指令結束符
E: 則是指定整段指令結束符 也就是說E 字元後面列印機自動不讀取識别的.
通過序列槽發送給列印機 指令完全正确 但DataMax-i-4208完全沒有反映,後來我聯系廠商才明白:
<STX>列印指令頭需要需要轉換16進制列印機才能識别 轉換後在TXT文本效果:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134535355.png"></a>
ok.通過序列槽工具發送指令給列印機 DataMax-i-4208終于開始響應 列印效果:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134543426.png"></a>
列印成功 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的查找快速定位你要找内容 雖然覺得這沒什麼 可是我要告訴你這種簡單效果 在一個非母語的文檔 效果還是非常好的:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134551322.png"></a>
詳細文法說明:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134600111.png"></a>
其他設定基本雷同,那麼在C#程式設計的話就要DPL指令格式限制問題. 類似我們制定X坐标即Row Offset的值 文法是R0037<CR>結束.首先X坐标的值範圍是0-9999,而且DPL規定格式必須是4位數. 也就是說類似設定X坐标為5 DPL标準識别格式:R0005<CR> C#進行控制:
/// <summary>
/// 處理資料寬高格式0000 列印指令0010
/// </summary>
public string ConvertDataFormat(float getvalue)
{
string converstr = string.Empty;
if (!string.IsNullOrEmpty(getvalue.ToString()))
{
//Convert Float to int type
string getfromtint = Convert.ToInt32(getvalue.ToString()).ToString();
if (4 - getfromtint.Length > 0)
{
for (int count = 0; count < 4 - getfromtint.Length; count++)
{
getfromtint = "0" + getfromtint;
}
converstr = getfromtint;
}
else
//長度超過或等于格式長度4
if (4 - getfromtint.Length == 0)
converstr = getfromtint;
else
converstr = string.Empty;
throw new EquipmentException("設定列印元素初始列印位置超過本地列印機設定 設定小于等于4位數");
}
return converstr;
}
針對<STX>列印标頭轉換 16進制控制:
/// Start Print CodeChar 指令:"<STX>L"
/// 轉換成16進制AS#格式
protected override string Leading()
#region 轉16進制資料
byte[] bytes = System.Text.Encoding.Default.GetBytes("<STX>L");
string reStr = string.Empty;
foreach (byte b in bytes)
{
short st = (short)(b - '\0');
reStr += st.ToString("x") + "%";
#endregion
return reStr;
擷取字型方法:
//字型設定
using System.Runtime.InteropServices;
[DllImport("fnthex32.dll", CharSet = CharSet.Ansi)]
public static extern int GETFONTHEX(
string chnstr,
string fontname,
int orient,
int height,
int width,
int bold,
int italic,
StringBuilder cBuf);
對于中文字型也就是Chinese Simple[中文簡體格式]是雙位元組 在DataMax中, 預設是不支援中文,類似我們把列印指令換成漢字 列印結果是出來字元亂碼 ??? 這是什麼問題. 我查了DAtaMAx官方對Chinese simple 中說明發現 如果需要DataMax列印中文則需要安裝字庫或在列印機上安裝中文字卡才能識别. 如果不安裝字卡 還有另外一種方式 采用第三方控件方式支援中文列印:
C#識别中文字元判斷:
/// 驗證是否是中文字元
public bool IsChinese(string getvalue)
return System.Text.RegularExpressions.Regex.IsMatch(getvalue, @"[\u4e00-\u9fa5]");
DPL手冊中對Chinese Simple中文簡體列印方式做了詳細說明 詳見DPL PDF文檔手冊285/250/254頁:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134617918.png"></a>
針對DataMax中文列印問題 DPL手冊中給了一個列印漢字 盒 的例子 可惜這個例子 我經過N多次嘗試 通過序列槽發送列印DPL 始終沒能成功使用這個例子. 後來詳細研究這個DPL 檔案.發現針對中文設定的文法其實很簡單:
//列印漢字DPL文法
<STX>L<CR>
ySPM<CR>
1911S0003100010P020P015 Chinese Available in GB r Set<CR>
yUGB<CR>
1911UC001200145P040P030<BA><D0><00><00><CR>
1911UC001200190P040P040<BA><D0><00><00><CR>
1911UC001200250P040P050<BA><D0><00><00><CR>
1911UC001200320P040P060<BA><D0><00><00><CR>
ySPM<CR>是列印語言和字型支援設定文法. ySPM是預設設定, yUGB則對應列印中文字型 這個設定很重要. 那麼我發現在DPL中并沒有漢字,其實DAtaMax針對列印漢字支援格式是GBK格式編碼 類似我們現在看到 漢字 盒 對應編碼就是<BA><DO><OO><OO>. C#中預設字元UNICODE格式這個得注意 需要把漢字重新轉碼在傳入DPL指令中 列印機才能識别. 列印出來結果是 4個盒字:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134626745.png"></a>
在來說列印條碼Code128格式 DPL指令:
//列印Code 128
1E000000015010001234567890<CR>
121100000000100Barcode E<CR>
輸出效果:
<a target="_blank" href="http://blog.51cto.com/attachment/201201/134634512.png"></a>
本文轉自chenkaiunion 51CTO部落格,原文連結:http://blog.51cto.com/chenkai/763885