office word文檔、pdf文檔、powerpoint幻燈片是非常常用的文檔類型,在現實中經常有需求需要將它們轉換成圖片 -- 即將word、pdf、ppt文檔的每一頁轉換成一張對應的圖片,就像先把這些文檔打印出來,然后再掃描成圖片一樣。所以,類似這種將word、pdf、ppt轉換為圖片的工具,一般又稱之為“電子掃描器”,很高端的名字!
一.那些場合需要將word、pdf、ppt轉換為圖片?
在我了解的情況中,通常有如下三種場景,有將word、pdf、ppt文檔轉換成圖片的需求。
1. 防止文檔被別人剽竊
如果直接將word、pdf、ppt文檔提供給他人,那么他人就可以很容易的Copy整個文檔的內容,然后稍作修改,就成為了他自己的東西。
如果我們將文檔轉換為圖片之后,再提供給他人,那么,剽竊就不僅僅是Copy一下那么容易了。
2. 節省紙張
以前為了更好的做到第1點,都是將文檔打印出來給別人看,很多文檔看一遍就不用了,所以會浪費很多紙張、浪費墨水、消耗打印機和電力。
在倡導低碳節能的今天,使用電子掃描器的意義就更大了。
3. 電子白板課件
類似在線教學、遠程培訓這樣的系統中,老師使用課件(word、pdf、ppt等類型的文檔)是基本的需求,課件與電子白板的結合方案一般是這樣的:將課件轉換成圖片,文檔的每一頁對應著電子白板的每一頁,而得到的圖片,正是作為白板頁的背景圖片。這樣,老師就可以在課件圖片上進行標注、板書了。我們前段時間研究word、pdf、ppt文檔轉圖片的技術,就是為了給OMCS的電子白板功能做一個擴展課件類型的Demo示例,讓其方便地支持word、pdf、ppt類型的課件。
二. 如何轉換?
問一下度娘,可以找到很多很多類似將word轉換為圖片的文章,但是,真正好用的并不多,篩選是個花時間的過程。在這里,我們直接把篩選的結果呈現出來,并且將其封裝成可以直接復用的Class,為以后有同樣需要的人節省時間。
1. 方案一:使用Office COM組件
(該方案不支持PDF文檔,關于PDF轉圖片的方法,這里有個很好的匯總,推薦給大家:PDF轉換成圖片的13種方案)
該方案的要求是用戶的電腦上必須安裝有微軟的Office,我們可以通過.NET與Office COM組件的互操作(Interop)來操作Office文檔。
該方案的原理是這樣的:通過COM互操作可以在內存中打開Office文檔,然后可以訪問文檔的每一頁,并且支持將任意一頁的內容復制到粘貼板(以圖的形式),這樣,我們再將粘貼板上的內容保存為圖片就搞定了。
原理很簡單,實現代碼稍微有點麻煩,如下所示:

private Bitmap[] Scan4Word(string filePath) { //復制目標文件,后續將操作副本 string tmpFilePath = AppDomain.CurrentDomain.BaseDirectory + "\\" + Path.GetFileName(filePath) + ".tmp"; File.Copy(filePath, tmpFilePath); List<Bitmap> bmList = new List<Bitmap>(); MSWord.ApplicationClass wordApplicationClass = new MSWord.ApplicationClass(); wordApplicationClass.Visible = false; object missing = System.Reflection.Missing.Value; try { object readOnly = false; object filePathObject = tmpFilePath; MSWord.Document document = wordApplicationClass.Documents.Open(ref filePathObject, ref missing, ref readOnly, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing); bool finished = false; while (!finished) { document.Content.CopyAsPicture(); //拷貝到粘貼板 System.Windows.Forms.IDataObject data = Clipboard.GetDataObject(); if (data.GetDataPresent(DataFormats.MetafilePict)) { object obj = data.GetData(DataFormats.MetafilePict); Metafile metafile = MetafileHelper.GetEnhMetafileOnClipboard(IntPtr.Zero); //從粘貼板獲取數據 Bitmap bm = new Bitmap(metafile.Width, metafile.Height); using (Graphics g = Graphics.FromImage(bm)) { g.Clear(Color.White); g.DrawImage(metafile, 0, 0, bm.Width, bm.Height); } bmList.Add(bm); Clipboard.Clear(); } object What = MSWord.WdGoToItem.wdGoToPage; object Which = MSWord.WdGoToDirection.wdGoToFirst; object startIndex = "1"; document.ActiveWindow.Selection.GoTo(ref What, ref Which, ref missing, ref startIndex); // 轉到下一頁 MSWord.Range start = document.ActiveWindow.Selection.Paragraphs[1].Range; MSWord.Range end = start.GoToNext(MSWord.WdGoToItem.wdGoToPage); finished = (start.Start == end.Start); if (finished) //最后一頁 { end.Start = document.Content.End; } object oStart = start.Start; object oEnd = end.Start; document.Range(ref oStart, ref oEnd).Delete(ref missing, ref missing); //處理完一頁,就刪除一頁。 } ((MSWord._Document)document).Close(ref missing, ref missing, ref missing); System.Runtime.InteropServices.Marshal.ReleaseComObject(document); return bmList.ToArray(); } catch (Exception ex) { throw ex; } finally { wordApplicationClass.Quit(ref missing, ref missing, ref missing); System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApplicationClass); File.Delete(tmpFilePath); //刪除臨時文件 } }
上述的實現對于小的word文檔很好用,但是,如果word文檔很大,有很多頁,那么,上述調用就會占用很大的內存。
如果是這種情況,那么,可以將上面的實現改寫一下,沒得到一頁的圖片就將其保存到硬盤,而不用在內存中保存了。
PPT轉為圖片也是用同樣的COM方式,文末會給出word和ppt轉圖片的COM實現的class下載。
2. 方案二:使用Aspose組件
使用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源碼下載:
2.方案二代碼下載
方案二的源碼可以從我們的示范demo中提取(客戶端項目中的ImageConverters.cs文件)。我們的示范demo用于模擬在線教育系統的場景:一個老師和N個學生進入同一個教室,所以,它們將看到同一個電子白板。老師可以上傳課件、打開課件、在白板課件上標注、板書等。該Demo在打開課件的時候,就用到了上面的將word、pdf、ppt轉換為圖片的功能。大家可以運行demo,看看具體的效果。
運行Demo進行測試時,可按如下流程:
(1)啟動OMCS服務端。
(2)啟動第一個客戶端,選擇“老師”角色,登錄進默認教室。
(3)再啟動多個客戶端,選擇“學生”角色,登錄進默認教室。
(4)老師即可進行上傳課件、打開課件、刪除課件、課件翻頁,在課件上標注、書寫,等等操作。
老師端運行界面截圖:
文章列表