天天看點

《互動式程式設計 第2版》一3.7 将外部資料載入Processing

本節書摘來華章計算機《互動式程式設計 第2版》一書中的第3章 ,第3.7節,joshua noble 著 毛順兵 張婷婷 陳宇 沈鑫 任燦江 譯更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

目前已經介紹了一些processing繪圖基礎和基本的使用者互動捕獲方式,你還要學習如何在processing中載入資料、圖像和視訊。前面已經提及processing項目的預設設定,知道了可以在和.pde同名的檔案夾下建立data檔案夾來存放所需的資料。processing應用程式希望把所有需要的資料都放入data檔案夾中。如果你想載入一個名叫sample.jpg的檔案,你應該把該檔案放到與正在處理的.pde檔案同名的檔案夾下的data檔案夾中。

首先,你要學會如何載入圖像。載入和顯示圖像的最基本的手段是一個類和兩個方法:pimage類、loadimage()方法和image()方法。

pimage類

processing依靠一個名為pimage的類來對圖像進行顯示和縮放。當你建立了一個pimage對象後,你就可以将圖像裝入到這個對象中,然後可将圖像顯示出來。想聲明一個pimage對象,可以在程式的任何地方聲明,但最好在程式代碼的頂端,如下所示:

pimage img;

在聲明了pimage對象之後,可以用loadimage()方法将圖像裝入到該對象中。

loadimage()方法

該方法将圖像檔案名作為參數,将此圖像裝入到pimage對象中。圖像檔案名既可以是檔案系統中的(具體到processing軟體,是你的項目目錄的data目錄中的檔案名),也可以是用url表示的檔案名。這意味着你可以裝入一個來自internet的圖像檔案,象下面這樣:

你也可以裝入你的項目目錄的data檔案夾中的圖像,像下面這樣:

loadimage()方法可以裝入jpeg、png、gif和tga格式的圖像。其他格式的圖像,如tif、bmp或raw,是無法用processing顯示的,除非對processing的一些方法進行認真修改。

你已經學習了如何聲明圖像對象和如何裝入圖像,剩下的就是如何用image()方法來顯示圖像。

image()方法

image()方法有3個參數:

第一個參數是要被顯示的pimage圖像對象。如果隻是聲明了該對象,還未用loadimage()方法建立它,那麼用image()方法去顯示它會引發一個錯誤。有一些技巧可以解決這個問題,我們留到第10章來講。在目前可以這樣講,一個pimage對象隻有在裝入圖像之後,才能用image()方法來顯示。另兩個參數是圖像放到視窗上以後左上角的x和y坐标,它們表明了圖像在視窗上的擺放位置。參考示例3-13。

示例3-13:image.pde

隻要setup()方法被調用,那麼視窗大小就确定了,圖像檔案sample.jpg就被裝入pimage對象并被顯示在視窗的(0,0)處(即視窗的左上角)。也可以用image()方法對pimage圖像對象中的圖形進行縮放。就象processing中的很多方法一樣,image()也是一組重載方法,你可以在調用時将想要的圖像寬度和高度作為參數傳遞給它:

如果沒有指明寬度和高度,圖像會以實際尺寸顯示在視窗上。如果圖像太大,就隻能顯示一部分。你也可以指定顯示時的寬度和高度,以便對圖像進行縮放。如果指定的寬高比和圖像實際的寬高比不一緻,那麼圖像會出現拉伸或擠壓現象。

processing程式包含了一個名為movie的類來顯示視訊。該類依賴蘋果公司的quicktime視訊處理庫,是以如果你的計算機還沒有安裝這個庫,你需要下載下傳并安裝它。要說明的是,目前在linux上用processing處理視訊是相當困難和複雜的。gsvideo庫很新,設定過程稍顯複雜;但它看起來相當可行,它允許linux使用者在processing中處理不同格式的視訊。為了本書的簡潔性考慮,我們将它留給讀者去自行研究。

用movie類可以裝入quicktime視訊;可以裝入擴充名為.mov的視訊檔案;可以播放、循環、暫停;可以改變播放速度;可以調整視訊色彩。用movie類建立視訊對象和用pimage類建立圖像對象有些相似,但也有一個很大的不同:你需要先導入包含movie類相關資訊以及視訊處理的所有庫。這些庫放置在另一個地方,可以用導入語句import來通路,如下所示:

接下來聲明一個movie變量:

在setup()方法中,你需要建立一個movie類的執行個體。如何建立呢?你可以調用movie類的構造函數。該類的構造函數也是一組重載方法,有4種簽名:

參數parent是将要使用和顯示視訊的processing應用程式。在簡單的應用程式中,參數parent往往是這個應用程式本身,是以你可以用關鍵字this來引用它:

這不是非了解不可的。每一個processing應用程式都是名為papplet的java類的執行個體。papplet類調用setup()方法和draw()方法,處理滑鼠和鍵盤事件。有時,一個應用程式執行個體被載入另一個應用程式中,内部的那個稱為papplet子對象,外部的稱為papplet父對象。如果在子對象中引用父對象,那麼父對象就是居于外部的那個應用程式。這點比較高深難懂,你多半也不想面對它。如果你遇到parent參數使用this關鍵字或papplet對象作實參,你會知道這些實參都引用主程式類。

用filename和url參數表示視訊檔案都是可行的,這就象用loadimage()方法裝載本地圖像和網絡上的圖像一樣。當要載入本機上的一個.mov檔案時,用該檔案的檔案名。當要載入網絡上的一個視訊時,就用url方式。最後有可選的參數fps表示幀速率。如果視訊自身的幀速率和應用程式的幀速率不同,你可以用這個參數設定讀取視訊時的幀速率。下面的代碼在processing應用程式的setup()方法中,使用對該程式的引用和本地視訊檔案作為參數,進而構造了一個movie對象:

看看代碼中的play()方法。它告訴processing應用程式要立刻讀取視訊檔案。這很重要,因為如果不調用這個方法,那麼processing應用程式就不會從視訊中讀取視訊幀,也就不會顯示視訊。想要讓processing應用程式顯示視訊,你必須調用play()方法或loop()方法。

要讀視訊,你需要定義一個movieevent()方法。為什麼呢?當quicktime播放視訊時,視訊片段或幀(和視訊幀沒有太大差別)源源不斷地流向processing應用程式,而processing應用程式會将它們顯示在視窗上。quicktime播放器準備好一個視訊幀後,通過調用movieevent()方法來告訴processing環境,一個視訊幀準備顯示了。這和mousepressed()的原理是一樣的,mousepressed()告訴processing環境發生了滑鼠按鍵事件。想要獲得該幀的資訊,你需要調用movie類的read()方法。該方法讀取一幀的資訊并放到movie對象中,準備顯示出來:

要在視窗中顯示目前視訊幀,你可以用image()方法。這與前面所講的用image()方法來顯示pimage對象中的圖像一樣。

這段代碼将目前視訊幀顯示在(0,0)處(即視窗左上角)。圖3-7是示例3-14的應用程式運作時的畫面。

示例3-14:movie.pde

《互動式程式設計 第2版》一3.7 将外部資料載入Processing

圖3-7:用movie類顯示視訊

最後還要了解如何讀寫檔案。要讀一個檔案有兩種方式,其中一種就是根據檔案類型使用對應的載入方法。要載入圖像,可以用loadimage()方法;要載入簡單文本檔案,可以用loadstrings()方法;要載入二進制檔案(除文本檔案之外的其他檔案),可以用loadbytes()方法。由于載入和分析二進制檔案要複雜得多,我們将這些内容留到第12章來講,本節隻講簡單文本檔案的讀寫。

loadstrings()方法

僅當要載入純文字檔案時,loadstrings()很有用。這就意味着,要用它來載入像word文檔這樣的檔案不會如你期望的那樣順利,因為word文檔中除了少量文本以外還包含了大量二進制資料。一般來講,以.txt為擴充名的檔案和沒有擴充名的純文字檔案都是純文字檔案。也就是說,用notepad和textedit建立的檔案一定可以用loadstrings()方法正确載入。要用loadstrings()方法載入檔案,括号中的參數既可以是本地電腦中的檔案名,也可以是用url方式表示的網絡檔案:

僅僅将文本檔案載入還不夠,還需要将檔案内的資料存放在某個地方。比如,将資料存放在一個字元串對象數組中:

這條語句建立了一個字元串數組來存放文本檔案的所有行,數組中的每個元素可以引用檔案中的一行。要顯示這些字元串,需要用一個for循環。每一次循環,都會用text()方法将一個字元串顯示在視窗畫布上。參見示例3-15。

示例3-15:loadstringsdemo.pde

再次提醒一下,所用到的文本檔案必須位于processing應用程式目錄下的data檔案夾中,或者來自internet。

savestrings()方法

前面介紹了用loadstrings()方法從文本檔案中讀取所有字元串,現在再學習如何将若幹字元串輸出到文本檔案就很容易了。這兩種操作是相反的。首先,需要建立字元串數組:

建立字元串數組之後,調用savestrings()方法就可以将數組中的所有字元串寫到文本檔案中。當然,調用時需要将檔案名和數組名作為參數傳遞進去:

savestrings("data/greeting.txt", lines);

這條語句建立了一個名為greeting.txt的文本檔案,并将數組中所有字元串都寫到該檔案中,每個字元串在檔案中占據一行。

繼續閱讀