WPF解析PPT爲圖片

  偶遇須要解析 PPT爲單張圖片git

  其中,對於包含動畫的PPT頁,分別對動畫最後效果進行截取,即每一個連續動畫截取 (動畫N個)N+1(原圖)張ide

 

  http://git.oschina.net/jiailiuyan/OfficeDecoder動畫

  

using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Reflection;
using Aspose.Slides;
using Aspose.Slides.Animation;

namespace Helpers
{
    public static class PPTHelper
    {

        /// <summary> 獲取 PPT 文檔單頁中的Shape,此項爲動畫的觸發項 </summary>
        /// <param name="ieffect"></param>
        /// <returns></returns>
        private static AutoShape GetAutoShape(IEffect ieffect)
        {
            AutoShape autoshape = null;
            var effect = ieffect as Effect;
            var flag = BindingFlags.Instance | BindingFlags.NonPublic;
            // 在 IEffect 中,PPTXUnsupportedProps 是獲取觸發項的屬性
            var props = effect.TextAnimation.GetType().GetProperty("PPTXUnsupportedProps", flag);
            if (props != null)
            {
                var animation = props.GetValue(effect.TextAnimation, null);
                // 因爲 dll 混淆後,沒法直接獲取屬性的名稱且觸發項被設置爲了保護項,所以須要反射 ishape_0 獲取
                var ishapefield = animation.GetType().GetField("ishape_0", flag);
                var ishape = ishapefield.GetValue(animation);
                autoshape = ishape as AutoShape;
            }
            return autoshape;
        }

        /// <summary> 設置默認的 Slide 顯示內容,在有動畫的狀況下, ISlide 顯示的是編輯狀態下最終呈現的,所以要修改其屬性爲動畫播放狀態初始界面 </summary>
        /// <param name="islide"></param>
        /// <returns></returns>
        private static bool SetDefaultSlide(ISlide islide)
        {
            // ISlide 中的 Timeline.MainSequence 記錄的是動畫項
            var slidecount = islide.Timeline.MainSequence.Count;
            if (slidecount == 0)
            {
                return false;
            }

            for (int i = 0; i < slidecount; i++)
            {
                var ieffect = islide.Timeline.MainSequence[i];
                var autoshape = GetAutoShape(ieffect);
                foreach (var behavior in ieffect.Behaviors)
                {
                    // Behaviors 中暫時只須要判斷 SetEffect 項,由於其餘項設置的是緩動和位置,所以無需處理
                    var seteffect = behavior as SetEffect;
                    if (seteffect != null)
                    {
                        //由於在此有動畫設置此項爲可見,反推之,此項默認應該隱藏
                        if (seteffect.To.ToString() == "visible")
                        {
                            autoshape.Hidden = true;
                        }
                        continue;
                    }
                }
            }
            return true;
        }

        public static List<string> ConvertToImages(string pptfile, string savedirectory = "")
        {
            // 返回的圖片絕對路徑集合
            List<string> images = new List<string>();

            // 獲取 Word 文件名稱
            var pptname = System.IO.Path.GetFileNameWithoutExtension(pptfile);

            // 若是指定了保存路徑,則使用傳入的路徑,不然在 Pdf 文件的同級建立同名文件夾看成保存路徑
            savedirectory = string.IsNullOrWhiteSpace(savedirectory) ? System.IO.Path.GetDirectoryName(pptfile) : savedirectory;
            savedirectory = System.IO.Path.Combine(savedirectory, pptname);
            // 防止保存的路徑不存在所以建立保存文件夾
            Directory.CreateDirectory(savedirectory);

            var pres = new Presentation(pptfile);

            int pptcount = pres.Slides.Count;
            for (int p = 0; p < pptcount; p++)
            {
                var item = pres.Slides[p];
                var imagefile = System.IO.Path.Combine(savedirectory, p + ".jpg");

                if (!SetDefaultSlide(item))
                {
                    // 獲取 2 倍的圖像,用以解決 PPT 內容太小時分辨率太小 ,下同
                    item.GetThumbnail(2.0f, 2.0f).Save(imagefile);
                    images.Add(imagefile);

                    continue;
                }
                imagefile = System.IO.Path.Combine(savedirectory, p + "_0.jpg");
                item.GetThumbnail(2.0f, 2.0f).Save(imagefile);
                images.Add(imagefile);

                // 在此每個動畫須要截圖一次,由於每個動畫都有本身的顯示內容
                var slidecount = item.Timeline.MainSequence.Count;
                for (int i = 0; i < slidecount; i++)
                {
                    var ieffect = item.Timeline.MainSequence[i];
                    var autoshape = GetAutoShape(ieffect);
                    try
                    {
                        foreach (var behavior in ieffect.Behaviors)
                        {
                            var seteffect = behavior as SetEffect;
                            if (seteffect != null)
                            {
                                //因爲此屬性標識當前項可見,因而須要還原狀態用以截圖
                                autoshape.Hidden = seteffect.To.ToString() != "visible";
                                continue;
                            }
                        }
                    }
                    catch { }
                    imagefile = System.IO.Path.Combine(savedirectory, p + "_" + i + ".jpg");
                    item.GetThumbnail(2.0f, 2.0f).Save(imagefile);
                    images.Add(imagefile);
                }
            }

            return images;
        }

        /// <summary> 獲取 PPT 中包含動畫的全部可顯示的 Bitmap </summary>
        /// <param name="path"> PPT 文件路徑 ,能夠爲 .pptx .ppt .pptm </param>
        /// <returns> 包含了全部動畫頁的圖像 </returns>
        public static List<Bitmap> GetPPTImages(string path)
        {
            var bmps = new List<Bitmap>();
            var pres = new Presentation(path);
            foreach (var item in pres.Slides)
            {
                if (!SetDefaultSlide(item))
                {
                    // 獲取 2 倍的圖像,用以解決 PPT 內容太小時分辨率太小 ,下同
                    bmps.Add(item.GetThumbnail(2.0f, 2.0f));
                    continue;
                }

                bmps.Add(item.GetThumbnail(2.0f, 2.0f));

                // 在此每個動畫須要截圖一次,由於每個動畫都有本身的顯示內容
                var slidecount = item.Timeline.MainSequence.Count;
                for (int i = 0; i < slidecount; i++)
                {
                    var ieffect = item.Timeline.MainSequence[i];
                    var autoshape = GetAutoShape(ieffect);
                    try
                    {
                        foreach (var behavior in ieffect.Behaviors)
                        {
                            var seteffect = behavior as SetEffect;
                            if (seteffect != null)
                            {
                                //因爲此屬性標識當前項可見,因而須要還原狀態用以截圖
                                autoshape.Hidden = seteffect.To.ToString() != "visible";
                                continue;
                            }
                        }
                    }
                    catch { }

                    bmps.Add(item.GetThumbnail(2.0f, 2.0f));
                }
            }

            return bmps;
        }

    }
}
View Code
相關文章
相關標籤/搜索