1. 程式人生 > >基於IE核心的多媒體檔案視覺化程式實現(一)

基於IE核心的多媒體檔案視覺化程式實現(一)

目的

前回書說道,在訊號處理或演算法研究中,資料的視覺化可以直觀地展現和判別結果的合理性。如果只允許用C語言做開發,或要將C語言所做演算法的輸出資料進行展示,又不許用MATLAB、Python所帶的視覺化工具,那麼,最快捷而直接的辦法就是將資料以文字方式輸出,再用Gnuplot工具來作圖了。Gnuplot可以直接生成png或svg圖片,Gnuplot所得的動畫圖還可以用gif格式儲存。這樣,通過WEB伺服器,就可以呼叫生成結果在WEB上展示了。

一般,windows中的看圖軟體是不支援gif動畫顯示的,我們會找一些看圖小工具軟體來顯示gif動圖,或利用瀏覽器直接開啟本地gif檔案。但總覺不夠方便,也顯得不夠專業。特別地,在自己的軟體產品中,應該使用自己介面的圖形視覺化視窗,而不是帶有第三方標記的東西。基於這種需求,我們特別需要有自己的本地檔案瀏覽工具。在開發中可用,在產品中也可用。

基於微軟的IE核心可以實現強大的html解析功能,而網頁中所能展現的檔案格式。IE瀏覽器核心也都能解析。許多第三方的瀏覽器都採用或至少相容了IE核心。這裡,我們採用IE核心作為多媒體檔案的解析和瀏覽工具,嘗試以最少的自編程式碼(基於VC++ MFC自動生成的程式碼量不計在內),去完成一個簡潔而功能強大的本地檔案瀏覽工具,具能使用命令列呼叫,這樣C語言就能編寫直接可看視覺化結果的程式了。

功能和特徵

如上回書說的,我們這個多媒體圖片瀏覽工具應具有如下功能和特徵:

  • 能顯示各種格式的點陣圖圖片 (是一個看圖軟體)
  • 能顯示向量圖(svg,wmf,emf)
  • 能顯示動畫(gif)或flash的swf
  • 能看各種格式的視訊 (是一個視訊播放器)
  • 能播放音訊檔案 (是一個音訊播放器)
  • 能閱讀pdf格式文件 (是一個Acrobat Reader)

還要求:

  • 這個軟體要是有原始碼的(自己編寫的)
  • 無商業版權衝突的,可以帶上自己的LOGO。
  • 在軟體體積上不能太大,最好在1M以內。
  • 這個軟體是以命令列模式工作的。
  • 而且編寫的程式碼量在100行以內。

實現思路

  • 首先通過VC++ MFC框架實現IE瀏覽器核心的嵌入,使之能瀏覽指定網頁。這個有多種方法可實現,最簡單的是採用Chtmlview類,以MFC工程嚮導自動產生程式碼,不必多寫一行程式碼即可實現。
  • 然後,將瀏覽物件改為本地圖片檔案或本地html檔案,使之能正確瀏覽顯示。這裡只需改一句程式碼。
  • 通過命令列引數將要開啟瀏覽的檔案路徑引數傳遞進去,使IE核心的瀏覽物件指向該檔案。這裡需要解析輸入的命令列引數,這用幾十行程式碼可完成。
  • IE瀏覽器核心可直接開啟常見圖片格式的檔案,如png,bmp,jpg,動圖gif,向量圖svg,微軟的 emf,wmf 格式等等,也能開啟pdf檔案(前提是IE瀏覽器裝有acrobat的pdf外掛。)
  • 對於有些檔案,特別是多媒體檔案,如mp3,wav,avi,swf等,IE核心不能直接開啟,我們可以生成臨時的html程式碼,將所要顯示的多媒體檔案包裹起來,再呼叫這個臨時html檔案即可。

編碼

基於MFC面向物件的程式碼是層層包裹的,隱藏實現,用巨集作訊息對映,微軟MFC甚至連winmain函式都給隱藏了,優點即是缺點,這讓我想起喬治·奧威爾的名言:“戰爭即和平, 自由即奴役, 無知即力量”。我們在此就不求甚解好了。

第一個程式(嚮導生成,不改程式碼)

基於Chtmlview類的MFC應用程式:開啟VC++整合環境(以 VC++6 為例, VS2010也一樣),Ctrl+N 新建立一個工程,假設工程名為wsee,通過嚮導建立MFC應用程式。一切都選預設引數即可。 在這裡插入圖片描述

只是到了最後一步(step6 of 6),將CWseeView基於CHtmlView基類即可。

在這裡插入圖片描述 點選OK即生成工程程式碼。

在這裡插入圖片描述

立即編譯(F7)之,應能通過。執行之,將會看到這樣的結果: 在這裡插入圖片描述

這是一個基於MFC多文件結構的IE瀏覽器嵌入模板。由於是VC6,很早了,所以指向的微軟網頁已經找不到了。但程式執行的正確的。

第二個程式(修改網頁指向)

開啟wseeView.cpp, 檢視其函式OnInitialUpdate(), 如下:

void CWseeView::OnInitialUpdate()
{
	CHtmlView::OnInitialUpdate();

	// TODO: This code navigates to a popular spot on the web.
	//  change the code to go where you'd like.
	Navigate2(_T("http://www.microsoft.com/visualc/"),NULL,NULL);
}

可見其中htpp指向。將其改為http://www.wtclab.net/ 試試?

Navigate2(_T("http://www.wtclab.net/"),NULL,NULL);

編譯執行,得到: 在這裡插入圖片描述

可見,只要改變Navigate2函式的訪問字串,即可顯示相應網頁內容。

假設在本地硬碟上有一個檔案, 其絕對路徑是d:\wsee\e1.gif, 則將字串file://d:/wsee/e1.gif 放入Navigate2函式,則可看到e1.gif動圖。 在這裡插入圖片描述 在這裡插入圖片描述 可見這樣的設計思路是可行的。

第三個程式(精簡和自定義)

VC++預設的模板可能不符合我們的需要,因此在建立工程時要依據需求重新選擇。

  • 單文件框架更合適。
  • 不需要選單、工具欄、狀態列等,就一個簡單說視窗即可。
  • 要用自己的圖示。

為此,刪除剛才新建的wsee工程及目錄,重新建立wsee工程。這回選MFC單文件模式,且不用工具欄和狀態列。選單不能去掉,要在程式碼中改。 在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述 將網址改成指向微軟主網站: 在這裡插入圖片描述 執行後即得: 在這裡插入圖片描述

我們去掉選單欄: 在CMainFrame::PreCreateWindow(CREATESTRUCT& cs)函式中,增加:

cs.hMenu = NULL;//即 選單控制代碼賦值為空

即可。

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	cs.hMenu = NULL;//即 選單控制代碼賦值為空
	return TRUE;
}

將Navigate2中的連結指向百度試試。得到 在這裡插入圖片描述

這樣就符合最簡視窗的要求了。

可以通過VC的資源管理器修改系統圖標(16*1632*32兩種),然後重新編譯即得自己圖示的程式了,雕蟲小技而已。

在這裡插入圖片描述 在這裡插入圖片描述

釋出為Relaese版本(24K)

在這裡插入圖片描述 可在VC++的build選單中Set Active Configuration 來設定編譯為釋出版本而非除錯版本。

Debug 版本為113KB, 釋出版本僅24KB,其實,程式只是做了一個外殼,核心是windows系統是自帶的IE瀏覽器在背後工作呢。

第四個程式(命令列引數引入)

顯然, 只要通過命令列引數引入要訪問的檔名,即可完成基本的圖片檔案顯示。

但是,查MFC的Navigate2函式說明發現,該函式只接受絕對路徑的檔案訪問。因此,如光想要在命令列引數中只使用檔名或相對路徑,則需要在程式中將輸入字串轉為絕對路徑方可正確應用。

另外一個問題是,如果我們還想利用這個程式訪問網際網路上的網頁,又該如何做?顯然採用條件句判斷是本地檔案還是遠端網址,分別處理即可。

如何實現? 且看下回分解。