2014年7月27日 星期日

GPUImage 滿漢大餐: 下載 GPUImage & 編譯成 Framework 來使用

繼續之前的部份,要使用第三方 Library 的第一個步驟就是先下載它,
那麼就來下載吧。

下載

GPUImage git 頁面的網址是:https://github.com/BradLarson/GPUImage
有幾個下載的方法,這邊我就教其中的兩個。

第一個:直接下載,這是最簡單的方式,只要找到右邊的 Download ZIP,就可以下載它了。

第二個:使用 git clone 來下載它,在 Download ZIP 的上方能找到 HTTPS clone URL,那邊就是下載用的網址,
只要下在終端機中下 "git clone 網址" 這個指令就能了。

下載完成後到你下載的目錄中找到 GPUImage 的目錄,
這時候能看到這些檔案,如下圖

檔案的用途與說明如下:
build.sh這是要編譯成 Framework 的檔案,這等等會教怎麼使用。
examples這是範例的資料夾,這個有興趣的人就自己看吧
framework原始檔案都放在這裡面,不想使用 Framework 的人可以直接使用裡面的檔案
GPUImage.podspec這是 Cocoa Pod 的描述檔,不過這邊不會用到它
License.txt這是放這個第三方 Library 使用哪個 License,在這邊是使用 BSD-style License
README.md這是這個第三方 Library 的基本描述與說明

使用

下載完畢後就是將它放入自己的專案中使用,
在 GPUImage 的目錄中找到 framework 下面的 Source 資料夾,
這個資料夾裡面都是放著 GPUImage 的原始檔案,
所以這個資料夾可以直接放入你自己的專案中使用。

編譯成 Framework

剛剛說到的 build.sh 是編譯成 Framework 來用的,
但是在編譯之前有一件事要做,
build.sh 裡面有一個參數要修改,
所以要先用文字編輯器來打開它,看你們習慣用哪一個打開就用那一個吧,

它個前段內容如下:
#!/bin/bash

set -e

IOSSDK_VER="7.0"

# xcodebuild -showsd

在那裡面能找到 IOSSDK_VER="7.0" 這一行,
這是在描述你的 iOS SDK 的版本,它個預設是使用 7.0,
如果你想要編譯成 6.0 版本的人,可以將它改成 6.0,
修改完之後將它存檔,可以準備進行編譯了。

開始編譯之前,請檢查一下 build.sh 的檔案屬性是否為 "可執行" 的,
檢查的方法是,請開啟你的終端機,切換目錄到 GPUImage 的目錄底下,
輸入 ls -la 的指令,就能看到這個目錄底下所有的檔案屬性。
(我在圖中輸入的 ll 就是 ls -la 的縮寫,這就與本次的主題無關,就不教如何使用了)

這時後檢查一下 build.sh 的檔案屬性有沒有如下的x
-rwxr-xr-x@ 1 darktt staff 1159 Jul 24 20:46 build.sh

如果沒有的話就請輸入以下指令:
chmod +x build.sh

這樣子就可以改變它的屬性了。

前面的準備工作都做完了,接下來就可以編譯了,
把剛剛開啟的終端機輸入以下指令,
./build.sh
這時候就能看到有一堆字跑出來,
如果看到的字是這樣子的話
xcodebuild: error: SDK "iphoneos7.0" cannot be located.
這就要修改一開始的 IOSSDK_VER="7.0" 了,
現在的最新版本是 7.1,所以要將它改成 7.1。

最後如果有看到
** BUILD SUCCEEDED **
這個的話那就代表正常結束了,

這時候就能看到多了一個資料夾,
這裡面就能找到 GPUImage.framework,
另外在 Release-iphoneos 能找到 libGPUImage.a 這個檔案,
(如果你只要使用模擬器的話就去 Release-iphonesimulator 找)
這兩個就是要放入你的專案中的檔案。

這樣子準備工作就全部結束了,
下次開始就要教正式的使用了,
下次再見。

2014年7月19日 星期六

GPUImage 滿漢大餐:序



這次是 GPUImage 的全套教學,
我會想這麼做的原因是,最近我有在用 GPUImage 開發一個 app,
但是在開發的過程中發現 GPUImage 的中文資源貧乏,並且它自己的說明文件也不齊全,
所以就想說我自己來做這一整套的教學了,不過這個教學是沒有截止的期限 XDD,
因此最好祈禱我不要中途而費。

什麼是 GPUImage?

GPUImage 是一個第三方的 API,
它整合了 OpenGL 與 AVFoundation,
並且支援 iOS 與 Mac 雙平台,
為了做到 Apple 一直不想做的濾鏡 (Filter) 的功能,

為什麼做是 Apple 不想做了?
因為根據 CoreImage 的 Framework 所提供的 CIFilter 只能做到一些陽春的濾鏡效果,
並且可修改的參數一大堆,導致開發者要一次又一次的測試,才能做出一個滿意的濾鏡較果,
這中間需要消耗大量個時間去做測試,這不是任何一位開發者願意看到的結果。

而 GPUImage 做到了,它提供更容易使用的環境,
並且結合了 AVFoundation 的相機、影像播放等功能、
讓開發者能做出一個相機的 app 並且能同時使用濾鏡做即時預覽的功能,
這是它強大之處。

章節

首先我先大概說明 GPUImage 的章節內容,
GPUImage 分為靜態圖像與動態影片兩個部分,
所以大章節就用這兩個做區分。

  1. 基礎上手篇:
    1. 下載 GPUImage
    2. 編譯成 Framework 來使用
  2. 相機篇:
    1. 做一個你自己的相機,用 GPUImage
    2. 用濾鏡處理你的相片
  3. 錄影篇:
    1. 來個即時濾鏡的攝影機,並且錄下你的生活
    2. 將你的生活影片染上不同的顏色與效果吧

目前是打算這麼做,
未來這一篇文章將會成為後續文章的索引,
當有後續文章出來之後我會將它加上連結,
方便大家使用。

2014年6月16日 星期一

Block in Swift

第一次學習 Block 就上手中教了在 Objective-C 的 Block 作法,
不過在 Swift 裡的作法又變了一個,所以才做了這個教學,
其實 Swift 的 Block 不叫做 Block,叫做 Closures,
它是一個將 Method 當做一個變數使用的應用。

一般的宣告方法如下
var aClosures: (NSString) -> Void = {string in
	NSLog("String: %@", string)
}

Closures 比較特別的是基本宣告都是宣告傳入或傳出的變數型態,
型態所對應變數名稱是在實作的時候才給予,這在基本宣告的時候還可以,
不過下面這個宣告方法就有可能看不懂了。

將 Closures 定義成一個型態之後再宣告
typealias bClosures = (NSNumber!) -> Void

var _bClosures:bClosures = {number in
	 NSLog("Number: %@", number)
;}

這時候如果不看這個型態內部定義的變數的話,就會完全不懂 number 這個變數是啥型態了,
這只能說 Swift 的風格特殊了。

接下來,有宣告當然就要有實作 Closures 的 Method,
其實實作 Method 的方法與 Block 的實作 Method 差異比較小,也可以說作法幾乎是相同的。

func methodWithaClosures(aClosures:(NSString) -> Void)
{
	NSLog("String: %@", string)
}

func methodWithbClosures(closures:bClosures)
{
	closures(NSNumber.numberWithInteger(150))
}

有實作了 Method,這時候就要回到上面將宣告好的 Closures 傳進去了。

var aClosures: (NSString) -> Void = {string in
	NSLog("String: %@", string)
}

typealias bClosures = (NSNumber!) -> Void

var _bClosures:bClosures = {number in
	 NSLog("Number: %@", number)
;}

self.methodWithaClosures(aClosures)

self.methodWithbClosures(_bClosures)

教學就到這邊,下次再看看有哪個東西需要教的了。

2014年5月15日 星期四

Class Method (三):Signleton 改 - 在多執行續的解法

在上一篇文章的 Class Method (二):Signleton 有在多執行續使用上的問題,
所以追加教學在多執行續中的 Signleton 的作法。

在舊的 signleton 的作法是這個樣子:
+ (id)method
{
	static Method *singleton = nil;
	if (singleton == nil) {
		singleton = [[Method alloc] init];
	}
	return singleton;
}

這在多執行續之下會有每個執行續都建立一個相同的 signleton 的問題,
所以要避免這個問題,就需要改寫 signleton 的寫法。

新個寫法如下,利用 GCD 的 dispatch_once 的方法來確保,
不管在哪個執行續下都是只有一個 signleton 的物件存在。
+ (id)method
{
	static Method *singleton = nil;
	
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		singleton = [DTFileController new];
	});
	
	return singleton;
}