c#實現ofd檔案轉圖片功能 (附執行程式)
前言 ofd檔案的作用就是保證資訊能如實的儲存、傳遞、顯示。保證ofd檔案的真實性靠的是簽名;ofd 的顯示需要專用軟體。ofd標準是新的國家標準,應用範圍遠不如pdf;現有瀏覽器不能解析ofd、支援ofd顯示的軟體也寥寥無幾。ofd轉圖片程式下載。
專用軟體讀取ofd過程包括對ofd檔案解壓縮、分析每頁的文字和圖元、關聯對應的資源、解析簽章等複雜操作。將ofd檔案轉成圖片,可以避免這些重複的操作;ofd轉成圖片後,就可以方便的在瀏覽器、各類app中顯示。所以,ofd轉圖片是ofd系統中必不可少的一個功能。
ofd轉圖片實現思路
ofd轉圖片沒有捷徑可走。實現ofd轉圖片,就是在圖片上輸出文字、圖元、各類曲線等,這些操作和輸出到螢幕上並沒有多大區別。ofd轉圖片和ofd閱讀器在技術上是有很大重合的。要完成ofd轉圖片,需要你對ofd檔案有充分的理解。參見我的文章《採用WPF技術,開發OFD電子文件閱讀器》。
本文ofd轉圖片功能沒用到wpf相關類,而是使用了System.Drawing暨GDI+。.net core 3.0 已經實現了System.Drawing;理論上,本文所涉及的程式碼可以很方便的移植到.net core下,在linux下實現ofd轉圖只有一步之遙。
實現ofd轉圖片包括以下幾個步驟:
1 建立ofd頁面資訊模型
ofd頁面由文字、圖片、曲線等組成。首先將頁面解析成各類object,它們的父類為PageObject:
public class PageObject { public string ID { get; set; } public PageLayer ParentLayer { get; set; } public string PageFileLoc => ParentLayer.ParentPage.PageFileLoc; XmlNode _xmlNode; public string Boundary { get; set; } public string CTM { get; set; } public OfdClipsGroup ClipsGroup { get; set; } public void SetPageObject(PageLayer layer, XmlNode xmlNode) { _xmlNode = xmlNode; ID = XmlHelper.GetXmlAttributeValue(xmlNode, "ID"); ParentLayer = layer; Boundary = XmlHelper.GetXmlAttributeValue(xmlNode, "Boundary"); CTM = XmlHelper.GetXmlAttributeValue(xmlNode, "CTM"); foreach (XmlNode childNode in xmlNode.ChildNodes) { if (childNode.Name == OfdClipsGroup.XML_Name) { ClipsGroup = OfdClipsGroup.FromXml(childNode); break; } } } public string GetAttributeValue(string name) { string result = XmlHelper.GetXmlAttributeValue(_xmlNode, name); return result; } }
從此類派生出 PageObjectText、PageObjectPath、PageObjectImage等,代表ofd頁面文字、曲線、圖片等型別資訊。
2 由資訊模型PageObject 建立顯示模型OfdVisual;
資訊模型包含了顯示需要的各類資訊,顯示模型就是利用這類資訊顯示。顯示模型的父類為OfdVisual:
public class OfdVisual { public OfdVisual() { } public virtual void Show(bool visiable, bool even = false) { } public virtual void ShowSelect(bool visiable, Rectangle selectRegion, bool even = false) { } public PointF BoundaryLocation { get; set; } public SizeF BoundarySize { get; set; } public Matrix ObjectTransform { get; protected set; } public Graphics VisualGraphics { get; set; } public PageObject PageObject { get; protected set; } public string PageItemId { get { if (PageObject == null) return string.Empty; return PageObject.ID; } }public PointF ToPageLocation(PointF pt) { return new PointF(pt.X + BoundaryLocation.X, pt.Y + BoundaryLocation.Y); } protected void PutBoundary() { VisualGraphics.TranslateTransform(BoundaryLocation.X, BoundaryLocation.Y); VisualGraphics.SetClip(ClipRect); } GraphicsState graphicsState; protected void DrawSave() { graphicsState = VisualGraphics.Save(); } protected void DrawRestore() { VisualGraphics.Restore(graphicsState); } protected void PutTransform() { if (ObjectTransform != null) { VisualGraphics.MultiplyTransform(ObjectTransform); } } public double XZoomRate { get { if (ObjectTransform == null) return 1; float result = ObjectTransform.Elements[0]; return result; } } public double YZoomRate { get { if (ObjectTransform == null) return 1; float result = ObjectTransform.Elements[4]; return result; } } }
有三類顯示模型OfdVisualText、OfdVisualImage、OfdVisualPath等。
3 建立bitmap
根據頁面大小建立bitmap,由bitmap獲取Graphics。後面的顯示操作就是利用Graphics各類函式處理。
_ofdBitmap = new Bitmap((int)(width* scale), (int)(height* scale)); Graphics = Graphics.FromImage(_ofdBitmap);
ofd轉圖片程式功能說明
操作步驟:選擇生成圖片的縮放比例,點選“ofd轉圖片”按鈕,選擇ofd檔案。轉成圖片後,ofd檔案在左側列表顯示,點選列表中檔案,右側顯示對應的圖片。程式底部為日誌,顯示ofd檔案的頁數、轉換耗時等資訊。
為了方便別的程式呼叫,程式可以做成web 服務形式,對外介面為web api。客戶端傳入ofd檔案,輸出為圖片。
後記 對於ofd轉圖片,網上有一種方法是採用虛擬列印。這是一種捷徑,也是沒有辦法的辦法。但是採用虛擬列印,必須依賴第三方ofd閱讀器,使用不方便,輸出效果也增加了不確定性。要實現ofd轉圖片,必須對ofd標準吃透,建立相應顯示模型,按部就班的實現轉圖功能;只有這樣,程式的功能才是自主可控、效率採有保