office word文档、pdf文档、powerpoint幻灯片是非常常用的文档类型,在现实中经常有需求需要将它们转换成图片 -- 即将word、pdf、ppt文档的每一页转换成一张对应的图片,就像先把这些文档打印出来,然后再扫描成图片一样。所以,类似这种将word、pdf、ppt转换为图片的工具,一般又称之为“电子扫描器”,很高端的名字!
在我了解的情况中,通常有如下三种场景,有将word、pdf、ppt文档转换成图片的需求。
如果直接将word、pdf、ppt文档提供给他人,那么他人就可以很容易的Copy整个文档的内容,然后稍作修改,就成为了他自己的东西。
如果我们将文档转换为图片之后,再提供给他人,那么,剽窃就不仅仅是Copy一下那么容易了。
以前为了更好的做到第1点,都是将文档打印出来给别人看,很多文档看一遍就不用了,所以会浪费很多纸张、浪费墨水、消耗打印机和电力。
在倡导低碳节能的今天,使用电子扫描器的意义就更大了。
类似在线教学、远程培训这样的系统中,老师使用课件(word、pdf、ppt等类型的文档)是基本的需求,课件与电子白板的结合方案一般是这样的:将课件转换成图片,文档的每一页对应着电子白板的每一页,而得到的图片,正是作为白板页的背景图片。这样,老师就可以在课件图片上进行标注、板书了。我们前段时间研究word、pdf、ppt文档转图片的技术,就是为了给OMCS的电子白板功能做一个扩展课件类型的Demo示例,让其方便地支持word、pdf、ppt类型的课件。
问一下度娘,可以找到很多很多类似将word转换为图片的文章,但是,真正好用的并不多,筛选是个花时间的过程。在这里,我们直接把筛选的结果呈现出来,并且将其封装成可以直接复用的Class,为以后有同样需要的人节省时间。
(该方案不支持PDF文档,关于PDF转图片的方法,这里有个很好的汇总,推荐给大家:PDF转换成图片的13种方案)
该方案的要求是用户的电脑上必须安装有微软的Office,我们可以通过.NET与Office COM组件的互操作(Interop)来操作Office文档。
该方案的原理是这样的:通过COM互操作可以在内存中打开Office文档,然后可以访问文档的每一页,并且支持将任意一页的内容复制到粘贴板(以图的形式),这样,我们再将粘贴板上的内容保存为图片就搞定了。
原理很简单,实现代码稍微有点麻烦,如下所示:
上述的实现对于小的word文档很好用,但是,如果word文档很大,有很多页,那么,上述调用就会占用很大的内存。
如果是这种情况,那么,可以将上面的实现改写一下,没得到一页的图片就将其保存到硬盘,而不用在内存中保存了。
PPT转为图片也是用同样的COM方式,文末会给出word和ppt转图片的COM实现的class下载。
使用Aspose组件的好处是,不需要用户的机器上安装Office,也可以完成我们想要的功能。这个优势实在是太明显了,所以,这是最推荐的方案。而且,Aspose完全支持word、ppt、和pdf,甚至excel也没问题。
我们在演示如何扩展OMCS电子白板课件类型的示范Demo中,采用的就是Aspose组件,感觉很稳定很好用。下面的代码就摘自示范Demo中。
public class Word2ImageConverter : IImageConverter { private bool cancelled = false; public event CbGeneric<int, int> ProgressChanged; public event CbGeneric ConvertSucceed; public event CbGeneric<string> ConvertFailed; public void Cancel() { if (this.cancelled) { return; } this.cancelled = true; } public void ConvertToImage(string originFilePath, string imageOutputDirPath) { this.cancelled = false; ConvertToImage(originFilePath, imageOutputDirPath, 0, 0, null, 200); } /// <summary> /// 将Word文档转换为图片 /// </summary> /// <param name="wordInputPath">Word文件路径</param> /// <param name="imageOutputDirPath">图片输出路径,如果为空,默认值为Word所在路径</param> /// <param name="startPageNum">从PDF文档的第几页开始转换,如果为0,默认值为1</param> /// <param name="endPageNum">从PDF文档的第几页开始停止转换,如果为0,默认值为Word总页数</param> /// <param name="imageFormat">设置所需图片格式,如果为null,默认格式为PNG</param> /// <param name="resolution">设置图片的像素,数字越大越清晰,如果为0,默认值为128,建议最大值不要超过1024</param> private void ConvertToImage(string wordInputPath, string imageOutputDirPath, int startPageNum, int endPageNum, ImageFormat imageFormat, int resolution) { try { Aspose.Words.Document doc = new Aspose.Words.Document(wordInputPath); if (doc == null) { throw new Exception("Word文件无效或者Word文件被加密!"); } if (imageOutputDirPath.Trim().Length == 0) { imageOutputDirPath = Path.GetDirectoryName(wordInputPath); } if (!Directory.Exists(imageOutputDirPath)) { Directory.CreateDirectory(imageOutputDirPath); } if (startPageNum <= 0) { startPageNum = 1; } if (endPageNum > doc.PageCount || endPageNum <= 0) { endPageNum = doc.PageCount; } if (startPageNum > endPageNum) { int tempPageNum = startPageNum; startPageNum = endPageNum; endPageNum = startPageNum; } if (imageFormat == null) { imageFormat = ImageFormat.Png; } if (resolution <= 0) { resolution = 128; } string imageName = Path.GetFileNameWithoutExtension(wordInputPath); ImageSaveOptions imageSaveOptions = new ImageSaveOptions(SaveFormat.Png); imageSaveOptions.Resolution = resolution; for (int i = startPageNum; i <= endPageNum; i++) { if (this.cancelled) { break; } MemoryStream stream = new MemoryStream(); imageSaveOptions.PageIndex = i - 1; string imgPath = Path.Combine(imageOutputDirPath, imageName) + "_" + i.ToString("000") + "." + imageFormat.ToString(); doc.Save(stream, imageSaveOptions); Image img = Image.FromStream(stream); Bitmap bm = ESBasic.Helpers.ImageHelper.Zoom(img, 0.6f); bm.Save(imgPath, imageFormat); img.Dispose(); stream.Dispose(); bm.Dispose(); System.Threading.Thread.Sleep(200); if (this.ProgressChanged != null) { this.ProgressChanged(i - 1, endPageNum); } } if (this.cancelled) { return; } if (this.ConvertSucceed != null) { this.ConvertSucceed(); } } catch (Exception ex) { if (this.ConvertFailed != null) { this.ConvertFailed(ex.Message); } } } }
代码相当简洁。在源码中,我们提供了Word2ImageConverter 、Pdf2ImageConverter 、Ppt2ImageConverter来分别用于word文档、pdf文档、ppt幻灯片到图片的转换。
有一点要注意的是,Aspose没有直接提供ppt转图片的API,但是,它提供了将ppt转为pdf的功能,所以,源码中实现ppt转图片是经过了pdf中转的,即:先将ppt文档转换为pdf文档,然后,在将pdf文档转换成图
1.方案一代码下载
方案一使用的Office COM互操作实现的,支持将word文档和ppt文档转成图片,class源码下载:
OfficeScanner.cs
2.方案二代码下载
方案二的源码可以从我们的示范demo中提取(客户端项目中的ImageConverters.cs文件)。我们的示范demo用于模拟在线教育系统的场景:一个老师和N个学生进入同一个教室,所以,它们将看到同一个电子白板。老师可以上传课件、打开课件、在白板课件上标注、板书等。该Demo在打开课件的时候,就用到了上面的将word、pdf、ppt转换为图片的功能。大家可以运行demo,看看具体的效果。
白板课件Demo
运行Demo进行测试时,可按如下流程:
(1)启动OMCS服务端。
(2)启动第一个客户端,选择“老师”角色,登录进默认教室。
(3)再启动多个客户端,选择“学生”角色,登录进默认教室。
(4)老师即可进行上传课件、打开课件、删除课件、课件翻页,在课件上标注、书写,等等操作。
老师端运行界面截图: