顯示具有 image_effect 標籤的文章。 顯示所有文章
顯示具有 image_effect 標籤的文章。 顯示所有文章

2010年3月24日 星期三

幫圖片加上影像特效 (IV) - 3D 投射效果

Create simple effects for your images (IV) - 3D Projection

在 Android SDK 中有兩種 Camera classes。一個是 android.hardware.Camera,這是用來操控相機功能的類別。另一個是 android.graphics.Camera,這是什麼東西?今天我們就要來研究一下,這個類別能幫我們做些什麼事。

android.graphics.Camera 是一個可以讓你將 2D 物件在 3D 空間中移動,並將在其移動後的結果,畫在螢幕上的類別。

聽起來很有趣,是嗎?例如,最上面那張美女圖,你可以看出來,他是將原本的圖,以 Y 軸為軸心,旋轉約 30 度後,所畫出來的結果。

打開 android.graphics.Camera 的說明文件,你會發現,這個文件中只有下面這些 APIs 列表,什麼說明都沒有。

不過,從這些 APIs 的名稱與參數,你應該可以猜出一些端倪。沒錯,這個 Camera class,其實是個 helper class。他提供一些 APIs ,讓你控制要如何在 3D 空間中移動,最後再產生出合適的 Matrix ,讓你套用到 Canvas 的座標體系上。關於 Matrix,我在 幫圖片加上影像特效 (I) - 陰影特效 已經介紹過他的強大,還不知道的,先讀一下這篇。

用個例子來解釋這個 Camera 類別的用法,是最適當的。底下這個簡單的程式片段的結果,就是最上面那張圖。其中的 m_bmp 就是原本的美女圖。

從這個範例程式中,我們知道,你可以利用 Camera.translate() 及 Camera.rotateXXX() 等 APIs 在 3D 空間中移動。其實,這些 APIs 就是在操作 Matrix 的內容。最後,你只要呼叫 Camera.getMatrix() 即可將這 Matrix 的內容抓出,並套到 Canvas 上。

在 Android ,要做出 3D 的效果,你當然可以用 OpenGL 的函式。不過,如果你需要更快的顯示速度,或者只是要做個簡單的 3D 特效,那千萬不要忘了這個 android.graphics.Camera。


繼續閱讀全文...

2010年1月25日 星期一

幫圖片加上影像特效 (III) - 負片與灰階效果

Create simple effects for your images (III) - Negative & Grayscale Effects

前兩次提過,簡單地利用 Matrix ,就可以輕易做出 陰影特效鏡像特效

這次,我將向大家分享,如何利用另一種 Matrix - ColorMatrix,來做出負片與灰階效果。

最上面那張圖的上半部,是原來的影像,一個美麗的地球。下半部的左邊,就是這地球影像的負片效果。右邊,則是灰階效果的呈現。

負片效果

負片效果的演算法,很簡單。就像底下這樣。

算法很簡單,可是在 Android 中要如何做到呢?難不成要用 Bitmap.getPixel()Bitmap.setPixel(),逐一針對每個像素來改他的顏色值?!

當然不是!這樣的做法,太沒效率,速度一定很慢。在 Android 中,針對這樣的需求,你可以透過 ColorMatrixColorFilter 來完成。在建構一個 ColorMatrixColorFilter 時,你得傳給他一個 ColorMatrix。因此,重點就在這個 ColorMatrix。

ColorMatrix 文件一開頭的註釋,就已經將他的功能講得很清楚。

讓我們看一下,這負片效果的原始碼,你會更加清楚。

將一個地球的圖片設給 m_bmp,透過上面這個程式範例,畫出來的樣子,就是一張具有負片效果的圖。

灰階效果

負片會了,灰階應該也很簡單了吧!我告訴你,要完成灰階效果,更簡單。ColorMatrix 都幫你將算法寫好了。你只要呼叫 ColorMatrix.setSaturation(0) 即可。

等等,學東西,可不能這樣就含混帶過。別忘了,Android 的原始碼都給你了,我們得利用他追根究柢,一探究竟才行。

打開 ColorMatrix.java 的原始碼,翻到 setSaturation()。這個函式的實現如下:

透過 android.graphics.ColorFilter 與 android.graphics.ColorMatrix,你還可以玩出更多的效果,別忘了 ApiDemos 的範例程式中,也有用到。

很多好東西,就在你身旁,千萬別捨近求遠了。


繼續閱讀全文...

2009年12月29日 星期二

幫圖片加上影像特效 (II) - 鏡像特效

Create simple effects for your images (II) - Reflection Effect

上次介紹過如何實現陰影特效,這次我將介紹如何實現 iMac 上常見的鏡像特效。

鏡像特效最近還蠻流行的,尤其在 HTC 的 Sense 介面上,常常都可以見到。最上面的那張圖,就是來自 HTC Sense 介面,所自帶瀏覽器程式中的『我的最愛』截圖。看到沒,加了個鏡像特效後,那感覺就很立體,感覺上好像是這些圖片擺立在一個玻璃桌面上。

我想你一定想知道,在 Android 上要幫圖片加上鏡像特效,會不會很麻煩?我告訴你,一點也不麻煩。和陰影特效相似,同樣地,只要幾行程式,就可以搞定。

因此,在開始看答案之前,我會建議你要先有 Photoshop 的使用經驗。想想,如果用 Photoshop 要幫圖片加上鏡像特效,要如何做?我想一般不外乎是先複製個圖片,並將其垂直翻轉,接著再對這翻轉的圖片,加個由灰到黑的漸層 mask 即可。

如果你沒 Photoshop 的使用經驗,自己上網找一下,應該不難找到說明,像 ,還有 都有。

好了,讓我們來看一下答案。底下就是幫圖片加上鏡像特效的程式範例。

_DrawMirror() 函式是關鍵。還記得我剛剛說,用 Photoshop 要如何做出鏡像特效?第一步是先畫出垂直翻轉的圖片。

Android 繪圖座標體系預設的原點在左上角,X 軸往右是越來越大的正值,而 Y 軸往下,則是越來越大的正值。要畫出垂直翻轉的圖片,其實也就是要垂直翻轉整個繪圖座標體系。在 Android 中,要如何做?答案就是 canvas.scale(1.0f, -1.0f)。很簡單吧,沒想到給 scale() 函式一個負值,就可以翻轉相對應的軸。

在 Photoshop 中,做鏡像特效的第二步是要對這翻轉的圖片,加個由灰到黑的漸層 mask。

在 Android 中,要畫漸層色,那就一定得用 LinearGradient 這個類別。至於要對背景圖加上個 mask,就請參考一下 Paint 的 setXfermode() 函式。_Init() 這個函式,就是負責生成一個由灰到黑漸層 mask 的 m_paint 物件。

將一個地球的圖片設給 m_dw,透過上面這個程式範例,畫出來的樣子,就像下面這樣。是不是感覺這地球,放在一塊玻璃桌面上?


繼續閱讀全文...

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 上常見的鏡像特效。


繼續閱讀全文...