2009年12月15日 星期二

幫圖片加上影像特效 (I) - 陰影特效

Create simple effects for your images (I) - Shadow Effect

Android 從 1.0 開始,他提供給開發者的各式繪圖函式,就比同時期其他手機平台來的強大與好用。

有 Android 基礎的你,應該都知道,在 Android 中繪圖,必須得要透過 Canvas 這個物件。在 Canvas 中,我最欣賞的功能就是,他讓開發者可以透過 matrix,來操作整個繪圖座標體系的位移、旋轉、傾斜等等功能。另外就是 Android 的 2D 繪圖功能,也開始支援 alpha,alpha 也就是透明度,這是要做一張美圖時,不可或缺的功能。

有了 matrix,加上 alpha,再配合比 bitmap 更為抽象的 drawable 物件,那你要將圖形做各式各樣的變形,甚至於將上影像的特效,都將會是輕而易舉的事。回想在 Windwos 3.1 的那個年代,要做到我要介紹的這些特效,那真的很辛苦,你必須要將影像中的像素,一個一個抓出來,再透過一些影像處理的演算法,才有辦法做到。

我就舉兩個影像特效例子,來說明這 Android 的繪圖功能有多強大。首先,我先介紹陰影特效要如何做。

在寫地圖程式時,通常會加個 Overlay 物件在地圖上,用來標示某個景點的所在位置。要在地圖上畫個 Overlay,Overlay 這個類別已經提供一個很好用的 drawAt() 函式給你。你只要負責給他一個沒有陰影的 Drawable,他會自動幫你製造出陰影的效果。結果就像最上面這張圖一樣,每個圖案標示,都有個陰影,這讓這些標示,看起來就像立在地圖上一般。

drawAt() 這個函式的宣告如下:

從實際的使用中,我們可以發現當你傳入 false 給 shadow 時,他就會幫你製造出陰影的效果。

這個函式,怎麼這麼神奇!今天我將幫你們翻出他的原始碼,讓我們來看看這個 drawAt() 是如何實現的。

底下就是 drawAt() 的原始碼。你看,短短不到 20 行,就可以幫任何的圖片做出陰影的效果。

為了幫助大家理解他是如何做到的,我將他整理成下面的程式範例。

_DrawShadowImg() 就是負責製造出陰影效果的函式。

這畫出陰影的函式,主要就是運用 matrix 與 drawable 的 color filter 這兩個功能。首先是 m_dw.setColorFilter(),將整個圖片的顏色都轉成半透明的黑色。接著 canvas.translate() 將座標體系原點移到 nX, nY 的位置,而 canvas.skew() 與 canvas.scale() 則是將座標體系做個 x 軸方向的傾斜,與 y 軸方向的大小壓縮。最後,呼叫 m_dw.draw() 將圖片畫上,陰影就這麼產生出來了。

底下這張圖,就是上面這個程式片段的執行結果。

下回,我將介紹要如何實現 iMac 上常見的鏡像特效。

4 則留言:

android 享樂誌 提到...

謝謝分享,我最近也有使用 ColorMatrix 來對圖片作一些處理,很希望能多看到一些 Android 上圖片處理的技巧。

匿名 提到...

谢谢分享 只是我做的效果阴影的位置总是不对
希望老师能把坐标translate的数值能提供以下
谢谢

Bischoff 提到...

謝謝分享,
另外我想請教android在MapView與Overlay的實作部份,
比如MapView extends ViewGroup,
但Overlay不是View,
是怎麼做到讓Overlay可以畫在MapView上的??
因為maps相關的程式好像沒有開放,
看到您的分享,
覺得相關性蠻高的,且很有經驗,
是否可以發文討論google map在android的實做手法呢?
Overlay感覺跟Game的碰撞很像.. 還是我的觀念錯誤.

samlu 提到...

Hi Bischoff, 我的進階課程中有提到 Map & Overlay,部落格文章得等有空時寫囉。

張貼留言