偶遇須要解析 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; } } }