1. 程式人生 > >c#實現ofd檔案轉圖片功能 (附執行程式)

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標準吃透,建立相應顯示模型,按部就班的實現轉圖功能;只有這樣,程式的功能才是自主可控、效率採有保