最近和同学在做虚拟漫游校园的项目,其中有个需求是把传进工程里的PPT的内容转化成为一张张的图片以供漫游场景使用,经过了一番尝试,得到了一个可行的解决方案,于是就来和大家分享O(∩_∩)O。
先从VS这边讲起,首先在VS2012中新建一个C#工程,这里我建的C#工程名为PPTCovertToPicture,在默认生成的Program.cs中的Main函数中添加PPT转图片的核心代码(Open函数的第一个参数为想要转换的PPT的路径):
ApplicationClass pptApplication = new ApplicationClass();
Presentation pptPresentation = pptApplication.Presentations.Open("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\Colorful.ppt", MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
pptPresentation.SaveAs("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\haha1.jpg", PpSaveAsFileType.ppSaveAsJPG);
添加完毕后会报一堆的错,提示找不到类,于是有解决方法:
添加相应的类库,可以在工程下的“引用”目录中右键点击“添加引用”,也可以在菜单中找到“项目”->“添加引用”->“COM”也可以添加相应的类库:
这里我们需要添加两个程序集,一个是Microsoft Office (Office版本号) Object Library,一个是Microsoft.Office.Interop.PowerPoint
在弹出来的“引用管理器”视图中,如果你的电脑安装了WPS的话,WPS的程序集也会显示在这里,如图,这是WPS的程序集:
虽然WPS也提供了支持对Office编程的程序集(Office 11.0指的是Office 2003、Office 12.0是Office 2007、Office 14.0是Office 2010、Office 15.0是Office 2013),但是引入后我们上面添加的程序仍是不可用的,所以得找到微软提供的程序集,WPS的不用勾选。
这里我的电脑上安装的是Office 2010 Plus,所以找微软的Microsoft Office 14.0 Object Library,注意,这里有可能会找不到,因为我们在安装Office套件的时候基本都是选择的经典安装而不是完全安装,因此就会丢失.net和支持对Office编程的程序集,如果找不到的话,可以选择重装一个Office,选择完全安装,或者你Office的镜像安装还在的话可以用它通过“添加/删除程序”来对你的Office进行更新,这里就不细说了。
我们找到微软的Microsoft Office 14.0 Object Library 和Microsoft.Office.Interop.PowerPoint,如图:
点击确定,就完成了添加。OK,添加了相应的程序集后,在Program.cs中添加引用:
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
如果发现没法引用using Microsoft.Office.Core,请参照上面所说重装Office或者更新Office的文件。
添加了引用后,可能还会报错“无法嵌入互操作类型,请改用适用的接口”,如图:
解决方法:
选中项目中引入的dll,鼠标右键,选择属性,把“嵌入互操作类型”设置为False。
比如这段测试代码的问题出自ApplicationClass这个里面,然后这个类来自Microsoft.Office.Interop.PowerPoint这个类库,所以我们在“引用”中找到这个类库,点击“属性”,在属性面板中把“嵌入互操作类型”改成False
编译通过后,运行,成功!会发现PPT中的每一页都已经转化成了图片保存在相应的目录中。
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//PPT转图片
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
namespace PPTCovertToPicture
{
class Program
{
static void Main(string[] args)
{
//第一种写法
ApplicationClass pptApplication = new ApplicationClass();
Presentation pptPresentation = pptApplication.Presentations.Open("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\Colorful.ppt", MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
// pptPresentation.Slides.FindBySlideID(1).Export("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\IjustWanttoseesee", "jpg", 320, 240);
pptPresentation.SaveAs("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\haha1.jpg", PpSaveAsFileType.ppSaveAsJPG);
/*
* //第二种写法,不过这样写会把之前生成的图片覆盖,因为每次的名字都一样,设置个string改变图片的名称就可以了
ApplicationClass pptApplication = new ApplicationClass();
Presentation pptPresentation = pptApplication.Presentations.Open("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\Colorful.ppt", MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
foreach (Slide pptSlide in pptPresentation.Slides)
{
pptSlide.Export("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\heihei.png", "PNG", 960, 720);
}
*/
}
}
}
VS下的解决了,我们来看Unity3D的。
打开Unity3D,新建一个工程,然后新建一个.cs文件(这里我新建了一个PPTToPicture.cs),首要做的工作也是引入DLL程序集,在之前的vs2012的工程中,我们在解决方案的视图中右键一个程序集,选择“在对象浏览器中查看”:
在对象浏览器视图中,选中一个程序集,可以在右下方看见这个程序集的信息,由于之前using Microsoft.Office.Core和usingMicrosoft.Office.Interop.PowerPoint分别在Office和Microsoft.Office.Interop.PowerPoint中,因此我们得找到这两个程序集,其他的程序集我们可以不管,Unity3D的Editor\Data\Mono\lib\mono\unity\目录中包含了其他的程序集。
首先按照目录找程序集Office,如图这个程序集的目录是C:\Windows\assembly\GAC_MSIL\Office\14.0.0.0__71e9bce111e9429c\Office.dll,我们顺着目录去找,但是到了assembly目录后会发现这里面都是安装好的程序集,无法复制和移动,GAC_MSIL也被隐藏了,这时候可以用cmd命令的形式将需要的程序集复制出来。
以复制Office这个程序集为例,打开cmd,输入“cd\”跳转到C盘根目录,再输入“cdWindows\assembly\GAC_MSIL\Office\14.0.0.0__71e9bce111e9429c”跳转到Office程序集所在的目录:
跳转完成后,可以输入“dir *Office.dll*.*”来查看Office.dll是否在这个目录中
找到了就会提示找到,否则会提示找不到该文件
接着输入“xcopy *.* C:\Temp\ /s /r”复制这个dll出来,复制到我在C盘新建的文件夹Temp中
同理,将Microsoft.Office.Interop.PowerPoint.dll也复制出来,然后我们在Unity3D项目中新建一个文件夹,将这两个程序集拖进去,这时候会报一个错误,Could not load file or assembly'Microsoft.Vbe.Interop.. 还需要将Microsoft.Vbe.Interop.dll复制出来,将其拖入Unity3D中,这时候需要重启一下Unity3D。
导入dll后Unity3D工程简单目录结构如图:
PPTToPicture.cs:
using UnityEngine;
using System.Collections;
using Microsoft.Office.Interop.PowerPoint;
using Microsoft.Office.Core;
public class PPTToPicture : MonoBehaviour {
private string mPictureName;
private int mPictureNum;
// Use this for initialization
void Start () {
try
{
ApplicationClass pptApplication = new ApplicationClass();
Presentation pptPresentation = pptApplication.Presentations.Open("C:\\Users\\Administrator\\Desktop\\DeskPPT\\Colorful.ppt", MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoFalse);
// pptPresentation.Slides.FindBySlideID(1).Export("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\IjustWanttoseesee", "jpg", 320, 240);
// pptPresentation.SaveAs("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\haha1.jpg", PpSaveAsFileType.ppSaveAsJPG);
// pptPresentation.SaveAs("D:\\MFC Projects\\PPTCovertToPicture\\PPTCovertToPicture\\haha1.jpg");
mPictureName = "1";
mPictureNum = 1;
foreach (Slide pptSlide in pptPresentation.Slides)
{
pptSlide.Export("C:\\Users\\Administrator\\Desktop\\DeskPPT\\temp\\heihei"+mPictureName+".png", "PNG", 960, 720);
mPictureNum++;
//每次都更换生成的图片的名字,以免重名而被覆盖
mPictureName = mPictureNum.ToString();
}
Debug.Log("转换格式成功!");
}
//如果转换不成功则抛出异常
catch(UnityException e)
{
Debug.Log("转换格式失败!");
throw(e);
}
}
// Update is called once per frame
void Update () {
}
}
在Monodevelop编译器中不识别固定参数的更改,因此这里用foreach而不用saveAs,如果是用VS2012来编写Unity3D的程序的话就不需要考虑这个。
在编译过后,仍然会看到有错误信息,提示FileNotFoundException: Could not load file or assembly 'stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies.
这个问题猜测是由于Unity3D的framework版本与引入的Office和VS程序集的framework版本不同造成的,由于并不影响使用,这个bug没有深究,今后如果解决或者研究了是什么回事后再编辑这篇博文吧。
Monodevelop编译器也可以像VS那样直接在编辑器界面中导入程序集,这样会更方便写,同学朋友们自己尝试下吧。
将这个脚本放在相机上,运行,搞定~之后就可以做其他的扩展了~