2012年3月15日 星期四

[Linux] 使用 Tarball 更新 OpenSSL @ Ubuntu 10.04

又到了一年一度機器被掃的時刻了,這次碰到的問題是 OpenSSL 版本太舊,有資安疑慮。


然而在 Ubuntu 上安裝時,直接用 ./config 後,安裝完的路徑卻不太對。網路上有看到別人用 ln -s 的方式強制切換位置,但安裝其他軟體時,一樣容易碰到 openssl header 跟 openssl library 版本不合的問題,摸索一下才找到正確的解法。


$ sudo apt-get remove openssl libssl-dev


$ tar -xvf openssl-w.x.yz.tar.gz
$ cd openssl-w.x.yz
$ ./config --prefix=/usr
$ sudo make install


如此一來才安全地搞定了。確認 OpenSSL 版本:


$ openssl version -a


只是更新完還有一堆東西要重編 Orz


2012年3月13日 星期二

[Python] 使用 PyPNG (Python PNG encoder/decoder) 產生 PNG 圖檔

sequential color random color


因研究關係,需要產生一些圖片像素有特殊規則的圖檔,找了一下剛好有 PyPNG 可以使用。


Python PNG encoder/decoder:


$ tar -xvf pypng-0.0.12.tar.gz
$ cd pypng-0.0.12
$ sudo python setup.py install


程式碼:


import png
import random


rawRow = []
rawColumn = ()
width = 1024
height = 1024
for i in range(256):
        if len(rawRow) >= height:
                break
        if i == 0:
                continue
        for j in range(256):
                if len(rawRow) >= height:
                        break
                if j == 0 :
                        continue
                for k in range(256):
                        if len(rawRow) >= height:
                                break
                        if k == 0:
                                continue
                        if len(rawColumn) < width*3:
                                rawColumn = rawColumn + (i,j,k,)
                                #rawColumn = rawColumn + (random.randint(1,255),random.randint(1,255),random.randint(1,255),)
                        else:
                                rawRow.append( rawColumn )
                                rawColumn = (i,j,k,)


f = open("test"+str(width)+"x"+str(height)+".png","wb")
w = png.Writer(width,height)
w.write( f, rawRow )
f.close()


程式碼有點醜,但堪用 XD 所以還是好好珍惜光陰吧!


2012年3月12日 星期一

Android 開發教學筆記 - 研究 Renderscript 以 Gravity 為例


From: http://code.google.com/p/renderscript-examples/wiki/Gravity


這是一個重力特效的範例。看過 Renderscript HelloWorld 的架構後,很快就能了解 Gravity,他們倆是一樣的架構,只是畫圖的部份不一樣。


這邊有四個檔案 Gravity.java、GravityRS.java、GravityView.java 和 gravity.rs,以 GravityRS.java 和 gravity.rs 最為重要,因此挑這兩個檔案研究一下:


gravity.rs:


(gTouchX, gTouchY) 座標資訊


用來決定重力中心位置,這會從螢幕上的 TouchEvent 後,慢慢傳遞到這兩個變數,所以在畫面上任一點點一下,則改變重力中心位置


Point 資料結構(delta、座標和顏色)


用來紀錄每一個畫在螢幕上的點資訊,包括座標、顏色,而 delta 則是用來計算與重力中心距離相關的數值,在畫面上則是用來決定靠近重力中心的速率,也就是座標變化量


void initParticles()


用來初始化 Point 位置,首先先得知有多少 Point,接著得知 Width 跟 Height 後,把所有 Point 座標用亂數建立出來,並設定顏色,而靠近重力中心的座標變化量就先定為 0


int root()


計算各 Point 與重力中心點 (gTouchX, gTouchY) 的位置,並決定該 Point 移動到重力中心點的座標變化量(越接近移動越快)。最後,則是透過 rsgDrawMesh(partMesh); 畫出各個 Point,並且 return 1 代表 1ms 更新畫面一次,也代表座標會重算一次


GravityRS.java:


void init(RenderScriptGL rs, Resources res, int width, int height) 裡頭包括決定 Point 個數、用 Mesh 結構把 Point 集中起來(方便畫圖),剩下的則是相關的初始化動作。


Android 開發教學筆記 - 研究 Renderscript 以 HelloWorld 為例

ImportSample


此例是一個很簡單的 Renderscript 的 HelloWorld,程式跑起來後,螢幕上只會顯示一個 "Hello World!" 字串,並且隨著你點擊螢幕的位置,該字串就會在那個位置上顯示。


使用方式:


[File]->[Project]->[Android]->[Android Sample Project]->[Android 4.0]->[RenderScript > HelloWorld]


AddSampleProject


接著簡述架構,共有 4 個檔案需留意:


HelloWorld.java


HelloWorld.java 就像一般 Android app 中的角色,為一個 Activity,裡頭新增一個 HelloWorldView 後,再把它加到自身的 View 身上。除此之外,則是對 Android app 的程式流程資訊(onResume、onPause)傳給 HelloWorldView 處理。


HelloWorldView.java


HelloWorldView.java 是一個繼承於 RSSurfaceView 的物件,用來負責初始化 Renderscript 所需的環境資源,以及接收 View 上頭的事件資訊進行處理,例如 onTouchEvent 等,而此例則是接收 TouchEvent 的位置後,把資訊傳遞給 Renderscript 以決定畫字串的位置。


初始化 Renderscript 運行的環境:


RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
RenderScriptGL mRS = createRenderScriptGL(sc);
// Create an instance of the script that does the rendering
HelloWorldRS mRender = new HelloWorldRS();
HelloWorldRS mRender.init(mRS, getResources());


更新字串位置:


if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        mRender.onActionDown((int)ev.getX(), (int)ev.getY());
        return true;
}


HelloWorldRS.java


void init(RenderScriptGL rs, Resources res)


負責將 HelloWorldView 初始化 Renderscript 所需的執行環境資源接收起來,用全域變數紀錄。接著執行自身函數 void initRS()。


void initRS()


初始化 mScript 變數,將 Java 與 Renderscript 接起來。其中 mScript = ScriptC_helloworld 代表要使用 helloworld.rs 程式。初始化完後,再 bind 到 Renderscript 執行環境。


void onActionDown(int x, int y)


把座標資訊傳遞給 mScript(helloworld.rs) 使用。


HelloWorld.rs


HelloWorld.rs 的工作主要就只是依據指定的 (gTouchX, gTouchY) 座標把 "Hello World!" 字串印出。負責印出的函式是 int root(void),回傳的整數代表更新螢幕的時間(ms),如回傳 20ms 代表每 20ms 作一次 root 內容函式。


From: http://developer.android.com/guide/topics/renderscript/graphics.html
A root() function. This is the main worker function for your Renderscript and calls Renderscript graphics functions to render scenes. This function is called every time a frame refresh occurs, which is specified as its return value. A 0 (zero) specified for the return value says to only render the frame when a property of the scene that you are rendering changes. A non-zero positive integer specifies the refresh rate of the frame in milliseconds.


colorCode


因此,想要體會 20ms 執行 root 內容函式的話,那更新一下 helloworld.rs 片段程式碼,將 rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); 更新為 rsgFontColor(rsRand(1.0f), rsRand(1.0f), rsRand(1.0f), 1.0f); 如此一來,就可以看到字串顏色不斷得變化囉。(該程式碼只是字型顏色改成亂數產生而已)


最後一提,不曉得這是不是一個很傷硬體的範例?程式執行沒多久後,我那塊 PandaBoard 就會掛掉 :P 或許 root 裡頭改成回傳 200(ms) 也適合,因為 0.2 秒的反應速度對人來說還 ok 囉。


Android 開發教學筆記 - 學習 Renderscript 的足跡


From: Graphics Renderscript overview


接觸 Renderscript 一陣子了,盡管官方文件顯少,但最佳的學習方式就是大量的程式碼閱讀,久了就會熟習為啥有 A 還是 B 的架構。據說 Renderscript 一開始是要設計給圖形運算的,以高效能、跨平台為出發點,不知不覺就設計出可以平行運算的架構,所以學習 Renderscript 別忘了繪圖運算跟平行處理這兩個方向。


關於 Renderscript 相關程式碼:



我本身一開始是先接觸 HelloCompute 的,看懂之後又對 Carousel 的效果著迷,在沒有圖學背景,悄悄地啃食完了,深深覺得數學真的很奧妙。之後閒暇之餘,又看了 Fountain 、HelloWorld 、 Gravity 和 Balls 等範例,漸漸地就能夠把 Renderscript 雛形給建立好。


回憶起來,我覺得比較好的學習曲線:



  • 平行運算


    • HelloCompute> Balls


  • 繪圖運算


    • HelloWorld > Gravity > Fountain > Carousel 



從 HelloWorld 的架構下,就能夠搞懂怎樣初始化一些繪圖的架構,例如 int root() 回傳的數值可代表畫面更新的頻率等,而 HelloCompute 則是專門做平行運算的架構。之所以把 Balls 擺在平行運算是因為裡頭有一個在 Renderscript 中呼叫 rsForEach 啦,而 HelloCompute 是在 Java 端呼叫 mScript.forEach_root ,更簡單的範例請參考 Renderscript Part 2 吧,算是把 HelloCompute 從 mScript.forEach_root 快速改寫成 rsForEach 的方式。


除此之外,最近也有一篇 R. Jason Sams 寫的一篇 Levels in Renderscript ,也是不錯的效能測試的文章。