示例代碼
CIImageAccumulator類非常適合基于反饋的處理打月。顧名思義澡匪,它隨著時(shí)間的推移累積圖像數(shù)據(jù)缝左。本章介紹如何使用CIImageAccumulator對(duì)象實(shí)現(xiàn)一個(gè)名為MicroPaint的簡(jiǎn)單繪畫應(yīng)用程序温自,該應(yīng)用程序允許用戶在畫布上繪制以創(chuàng)建類似于圖7-1所示的圖像已维。
圖7-1 MicroPaint的輸出
“圖像”以空白畫布開始淆攻。MicroPaint使用圖像累加器來收集用戶應(yīng)用的繪制阔墩。當(dāng)用戶單擊“清除”時(shí),MicroPaint會(huì)將圖像累加器重置為白色畫布瓶珊。顏色井允許用戶改變油漆顏色啸箫。用戶可以使用滑塊更改畫筆大小。
為MicroPaint應(yīng)用程序創(chuàng)建圖像累加器的基本任務(wù)是:
- 設(shè)置MicroPaint應(yīng)用程序的界面
- 初始化繪畫的過濾器和默認(rèn)值
- 跟蹤和積累繪畫操作
本章僅介紹創(chuàng)建圖像累加器和支持圖形累加器所必需的代碼伞芹。此處不討論繪制到視圖和處理視圖大小更改的方法忘苛。為此,請(qǐng)參閱CIMicroPaint唱较,這是一個(gè)完整的示例代碼項(xiàng)目扎唾,您可以下載并更詳細(xì)地查看。CIMicroPaint有幾個(gè)有趣的細(xì)節(jié)南缓。它展示了如何繪制到OpenGL視圖并保持以前版本的OS X的向后兼容性胸遇。
設(shè)置MicroPaint應(yīng)用程序的界面
MicroPaint的界面需要以下內(nèi)容:
- 圖像累加器
- 用戶的“刷子”。筆刷是核心圖像濾鏡(CIRadialGradient)汉形,它以模擬氣刷的方式應(yīng)用顏色纸镊。
- 復(fù)合濾鏡(CISourceOverCompositing),允許新涂料與先前應(yīng)用的涂料合成概疆。
- 用于跟蹤當(dāng)前油漆顏色和刷子尺寸的變量逗威。
構(gòu)建過濾器字典聲明MircoPaintView為SampleCIView的子類。這個(gè)SampleCIView課不在這里討論; 它NSOpenGLView是類的子類届案。有關(guān)詳細(xì)信息庵楷,請(qǐng)參閱CIMicroPaint示例應(yīng)用程序。
清單7-1 MicroPaint應(yīng)用程序的界面
@interface MicroPaintView : SampleCIView {
CIImageAccumulator *imageAccumulator;
CIFilter *brushFilter;
CIFilter *compositeFilter;
NSColor *color;
CGFloat brushSize;
}
@end
初始化繪畫的濾鏡和默認(rèn)值
初始化MicroPaint應(yīng)用程序時(shí)(如清單7-2所示)楣颠,您需要?jiǎng)?chuàng)建畫筆和復(fù)合濾鏡,并設(shè)置初始畫筆大小和繪畫顏色咐蚯。清單7-2中的代碼已創(chuàng)建并初始化為透明黑色童漩,輸入半徑為0.當(dāng)用戶拖動(dòng)光標(biāo)時(shí),畫筆過濾器將采用畫筆大小和顏色的當(dāng)前值春锋。
清單7-2 初始化過濾器矫膨,畫筆大小和繪畫顏色
brushFilter = [CIFilter filterWithName: @"CIRadialGradient" withInputParameters:@{
@"inputColor1": [CIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0],
@"inputRadius0": @0.0,
}];
compositeFilter = [CIFilter filterWithName: @"CISourceOverCompositing"];
brushSize = 25.0;
color = [NSColor colorWithDeviceRed: 0.0 green: 0.0 blue: 0.0 alpha: 1.0];
跟蹤和積累繪畫操作
mouseDragged:只要用戶單擊或拖動(dòng)畫布上的光標(biāo),就會(huì)調(diào)用該方法。它會(huì)更新畫筆和合成濾鏡值侧馅,并為累積的圖像添加新的繪畫操作危尿。
設(shè)置圖像后,需要觸發(fā)顯示更新馁痴。您的drawRect:方法處理繪制圖像谊娇。繪制到CIContext對(duì)象時(shí),請(qǐng)確保使用drawImage:inRect:fromRect:而不是棄用的方法drawImage:atPoint:fromRect:罗晕。
清單7-3 設(shè)置刷子過濾器并將其應(yīng)用于累積圖像
- (void)mouseDragged:(NSEvent *)event
{
CGRect rect;
NSPoint loc = [self convertPoint: [event locationInWindow] fromView: nil];
CIColor *cicolor;
//創(chuàng)建一個(gè)以拖動(dòng)位置為中心的矩形
//其尺寸是當(dāng)前畫筆大小的兩倍
rect = CGRectMake(loc.x-brushSize, loc.y-brushSize,
2.0*brushSize, 2.0*brushSize);
//設(shè)置畫筆的大小
//回想一下济欢,這實(shí)際上是一個(gè)徑向漸變?yōu)V鏡
[brushFilter setValue: @(brushSize)
forKey: @"inputRadius1"];
cicolor = [[CIColor alloc] initWithColor: color];
[brushFilter setValue: cicolor forKey: @"inputColor0"];
[brushFilter setValue: [CIVector vectorWithX: loc.x Y:loc.y]
forKey: kCIInputCenterKey];
//將畫筆濾鏡的輸出與圖像合成
//由圖像累加器累加
[compositeFilter setValue: [brushFilter valueForKey: kCIOutputImageKey]
forKey: kCIInputImageKey];
[compositeFilter setValue: [imageAccumulator image]
forKey: kCIInputBackgroundImageKey];
//將圖像累加器設(shè)置為合成圖像
[imageAccumulator setImage: [compositeFilter valueForKey: kCIOutputImageKey]
dirtyRect: rect];
//設(shè)置圖像后,需要觸發(fā)顯示更新
[self setImage: [imageAccumulator image] dirtyRect: rect];
}