zoukankan      html  css  js  c++  java
  • WPF解析PPT为图片

      偶遇需要解析 PPT为单张图片

      其中,对于包含动画的PPT页,分别对动画最后效果进行截取,即每个连续动画截取 (动画N个)N+1(原图)张

      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
  • 相关阅读:
    XAML学习笔记之Layout(五)——ViewBox
    XAML学习笔记——Layout(三)
    XAML学习笔记——Layout(二)
    XAML学习笔记——Layout(一)
    从0开始搭建SQL Server 2012 AlwaysOn 第三篇(安装数据,配置AlwaysOn)
    从0开始搭建SQL Server 2012 AlwaysOn 第二篇(配置故障转移集群)
    从0开始搭建SQL Server 2012 AlwaysOn 第一篇(AD域与DNS)
    Sql Server 2012 事务复制遇到的问题及解决方式
    Sql Server 2008R2升级 Sql Server 2012 问题
    第一次ACM
  • 原文地址:https://www.cnblogs.com/jiailiuyan/p/4838509.html
Copyright © 2011-2022 走看看