update: 2013/04/18
套用個別濾鏡
A. 建立濾鏡類別
1. 基底濾鏡(用來讓其它濾鏡類別繼承使用)
a. Xcode > File > New > File...
iOS > Cocoa Touch > Objective-C class > Next
Class: FilterBase
Subclass of: NSObject> Next
Targets: Filter4Cam
> Create #import <Foundation/Foundation.h>
@interface FilterBase : NSObject
{
}
//@add for apply Filter
- (CIImage *)filterImage:(CIImage *)sourceImage;
//@add for debug use
- (void)showAllFilters; // 顯示內建可用的所有濾鏡名稱
- (void)showCategoryFilters:(NSString *)categoryName; // 顯示特定分類的濾鏡名稱
- (void)showFilterAttributes:(NSString *)filterName; // 顯示特定濾鏡的屬性
@end
c. 開啟 FilterBase.m 檔案, 修改如下:
#import "FilterBase.h"
@implementation FilterBase
//@add for apply Filter
- (CIImage *)filterImage:(CIImage *)sourceImage
{
return sourceImage; // just return the source
}
// 顯示內建可用的所有濾鏡名稱
- (void)showAllFilters
{
NSArray *properties = [CIFilter filterNamesInCategory:kCICategoryBuiltIn];
NSLog(@"\n AllFilters = \n %@", properties);
}
// 顯示特定分類的濾鏡名稱
- (void)showCategoryFilters:(NSString *)categoryName
{
NSArray *properties = [CIFilter filterNamesInCategory:categoryName];
NSLog(@"\n %@ Category: \n %@", categoryName, properties);
}
// 顯示特定濾鏡的屬性
- (void)showFilterAttributes:(NSString *)filterName
{
CIFilter *filter = [CIFilter filterWithName:filterName];
NSLog(@"\n %@ Filter: \n %@", filterName, [filter attributes]);
}
@end
*************************************************
2. 墨魚濾鏡(復古風格)
a. Xcode > File > New > File...
iOS > Cocoa Touch > Objective-C class > Next
Class: SepiaFilter
Subclass of: NSObject> Next
Targets: Filter4Cam
> Create
b. 開啟 SepiaFilter.h 檔案, 修改如下:
#import <Foundation/Foundation.h>
//@add
#import "FilterBase.h"
//@interface SepiaFilter : NSObject
//@update: 墨魚濾鏡
@interface SepiaFilter : FilterBase
{
}
@end
c. 開啟 SepiaFilter.m 檔案, 修改如下:
#import "SepiaFilter.h"
@implementation SepiaFilter
//@add for apply Filter
- (CIImage *)filterImage:(CIImage *)sourceImage
{
CIFilter *coreImageFilter = [CIFilter filterWithName:@"CISepiaTone"];
[coreImageFilter setValue:sourceImage forKey:kCIInputImageKey];
[coreImageFilter setValue:[NSNumber numberWithFloat:0.8] forKey:@"inputIntensity"];
return [coreImageFilter outputImage];
}
//@add
- (id)init
{
if (self = [super init]) {
//[self showAllFilters];
//[self showCategoryFilters:kCICategoryColorEffect];
//[self showCategoryFilters:kCICategoryColorAdjustment];
//[self showCategoryFilters:kCICategoryGenerator];
//[self showCategoryFilters:kCICategoryStylize];
//[self showFilterAttributes:@"CISepiaTone"];
/*
CISepiaTone Filter:
{
CIAttributeFilterCategories = (
CICategoryColorEffect,
CICategoryVideo,
CICategoryInterlaced,
CICategoryNonSquarePixels,
CICategoryStillImage,
CICategoryBuiltIn
);
CIAttributeFilterDisplayName = "Sepia Tone";
CIAttributeFilterName = CISepiaTone;
inputImage = {
CIAttributeClass = CIImage;
CIAttributeType = CIAttributeTypeImage;
};
inputIntensity = {
CIAttributeClass = NSNumber;
CIAttributeDefault = 1;
CIAttributeIdentity = 0;
CIAttributeMax = 1;
CIAttributeMin = 0;
CIAttributeSliderMax = 1;
CIAttributeSliderMin = 0;
CIAttributeType = CIAttributeTypeScalar;
};
}
*/
}
return self;
}
@end
*************************************************
3. 假色濾鏡(將圖片的內容對應到二種顏色)
a. Xcode > File > New > File...
iOS > Cocoa Touch > Objective-C class > Next
Class: FalseFilter
Subclass of: NSObject> Next
Targets: Filter4Cam
> Create
b. 開啟 FalseFilter.h 檔案, 修改如下:
#import <Foundation/Foundation.h>
//@add
#import "FilterBase.h"
//@interface FalseFilter : NSObject
//@update: 假色濾鏡
@interface FalseFilter : FilterBase
{
}
@end
c. 開啟 FalseFilter.m 檔案, 修改如下:
#import "FalseFilter.h"
@implementation FalseFilter
//@add for apply Filter
- (CIImage *)filterImage:(CIImage *)sourceImage
{
// 假色濾鏡(False Color filter), 將圖片的內容對應到二種顏色.
CIFilter *coreImageFilter = [CIFilter filterWithName:@"CIFalseColor"];
[coreImageFilter setValue:sourceImage forKey:kCIInputImageKey];
[coreImageFilter setValue:[CIColor colorWithRed:0.145 green:0.016 blue:0.308] forKey:@"inputColor0"];
[coreImageFilter setValue:[CIColor colorWithRed:0.972 green:0.912 blue:0.762] forKey:@"inputColor1"];
return [coreImageFilter outputImage];
}
//@add
- (id)init
{
if (self = [super init]) {
//[self showFilterAttributes:@"CIFalseColor"];
/*
CIFalseColor Filter:
{
CIAttributeFilterCategories = (
CICategoryColorEffect,
CICategoryVideo,
CICategoryInterlaced,
CICategoryNonSquarePixels,
CICategoryStillImage,
CICategoryBuiltIn
);
CIAttributeFilterDisplayName = "False Color";
CIAttributeFilterName = CIFalseColor;
inputColor0 = {
CIAttributeClass = CIColor;
CIAttributeDefault = "(0.3 0 0 1)";
CIAttributeType = CIAttributeTypeColor;
};
inputColor1 = {
CIAttributeClass = CIColor;
CIAttributeDefault = "(1 0.9 0.8 1)";
CIAttributeType = CIAttributeTypeColor;
};
inputImage = {
CIAttributeClass = CIImage;
CIAttributeType = CIAttributeTypeImage;
};
}
*/
}
return self;
}
@end
*************************************************
4. 顏色調節濾鏡(調整顏色的: 飽和, 對比與亮度)
a. Xcode > File > New > File...
iOS > Cocoa Touch > Objective-C class > Next
Class: ColorFilter
Subclass of: NSObject
> Next
Targets: Filter4Cam
> Create
b. 開啟 ColorFilter.h 檔案, 修改如下:
#import <Foundation/Foundation.h>
//@add
#import "FilterBase.h"
//@interface ColorFilter : NSObject
//@update: 顏色調節濾鏡
@interface ColorFilter : FilterBase
{
}
@end
c. 開啟 ColorFilter.m 檔案, 修改如下:
#import "ColorFilter.h"
@implementation ColorFilter
//@add for apply Filter
- (CIImage *)filterImage:(CIImage *)sourceImage
{
// 顏色調節濾鏡(調整顏色的: 飽和, 對比與亮度)
CIFilter *coreImageFilter = [CIFilter filterWithName:@"CIColorControls"];
[coreImageFilter setValue:sourceImage forKey:kCIInputImageKey];
// 亮度: -1~1 (default:0)
[coreImageFilter setValue:[NSNumber numberWithFloat:0.0] forKey:@"inputBrightness"];
// 對比度: 0~4 (default:1)
[coreImageFilter setValue:[NSNumber numberWithFloat:1.8] forKey:@"inputContrast"];
// 飽和度: 0~2 (default:1)
[coreImageFilter setValue:[NSNumber numberWithFloat:1.6] forKey:@"inputSaturation"];
return [coreImageFilter outputImage];
}
//@add
- (id)init
{
if (self = [super init]) {
//[self showFilterAttributes:@"CIColorControls"];
/*
CIColorControls Filter:
{
CIAttributeFilterCategories = (
CICategoryColorAdjustment,
CICategoryVideo,
CICategoryStillImage,
CICategoryInterlaced,
CICategoryNonSquarePixels,
CICategoryBuiltIn
);
CIAttributeFilterDisplayName = "Color Controls";
CIAttributeFilterName = CIColorControls;
inputBrightness = {
CIAttributeClass = NSNumber;
CIAttributeDefault = 0;
CIAttributeIdentity = 0;
CIAttributeSliderMax = 1;
CIAttributeSliderMin = "-1";
CIAttributeType = CIAttributeTypeScalar;
};
inputContrast = {
CIAttributeClass = NSNumber;
CIAttributeDefault = 1;
CIAttributeIdentity = 1;
CIAttributeSliderMax = 4;
CIAttributeSliderMin = 0;
CIAttributeType = CIAttributeTypeScalar;
};
inputImage = {
CIAttributeClass = CIImage;
CIAttributeType = CIAttributeTypeImage;
};
inputSaturation = {
CIAttributeClass = NSNumber;
CIAttributeDefault = 1;
CIAttributeIdentity = 1;
CIAttributeSliderMax = 2;
CIAttributeSliderMin = 0;
CIAttributeType = CIAttributeTypeScalar;
};
}
*/
}
return self;
}
@end
*************************************************
5. 複合濾鏡(在此為: "假色濾鏡" 與 "顏色調節濾鏡")
a. Xcode > File > New > File...
iOS > Cocoa Touch > Objective-C class > Next
Class: ComboFilter
Subclass of: NSObject
> Next
Targets: Filter4Cam
> Create
b. 開啟 ComboFilter.h 檔案, 修改如下:
#import <Foundation/Foundation.h>
//@add
#import "FilterBase.h"
//@interface ComboFilter : NSObject
//@update: 複合濾鏡
@interface ComboFilter : FilterBase
{
}
@end
c. 開啟 ComboFilter.m 檔案, 修改如下:
#import "ComboFilter.h"
@implementation ComboFilter
//@add
- (CIImage *)filterImage:(CIImage *)sourceImage
{
// 複合濾鏡 (在此為: "假色濾鏡" 與 "顏色調節濾鏡")
/* 假色濾鏡 */
CIFilter *coreImageFilter1 = [CIFilter filterWithName:@"CIFalseColor"];
[coreImageFilter1 setValue:sourceImage forKey:kCIInputImageKey];
[coreImageFilter1 setValue:[CIColor colorWithRed:0.145 green:0.016 blue:0.308] forKey:@"inputColor0"];
[coreImageFilter1 setValue:[CIColor colorWithRed:0.972 green:0.912 blue:0.762] forKey:@"inputColor1"];
/* 顏色調節濾鏡 */
CIFilter *coreImageFilter2 = [CIFilter filterWithName:@"CIColorControls"];
[coreImageFilter2 setValue:[coreImageFilter1 outputImage] forKey:kCIInputImageKey];
// 亮度: -1~1 (default:0)
[coreImageFilter2 setValue:[NSNumber numberWithFloat:0.0] forKey:@"inputBrightness"];
// 對比度: 0~4 (default:1)
[coreImageFilter2 setValue:[NSNumber numberWithFloat:1.8] forKey:@"inputContrast"];
// 飽和度: 0~2 (default:1)
[coreImageFilter2 setValue:[NSNumber numberWithFloat:1.6] forKey:@"inputSaturation"];
return [coreImageFilter2 outputImage];
}
//@add
- (id)init
{
if (self = [super init]) {
}
return self;
}
@end
-----------------------------------------------------------------------------
B. 儲存所有的濾鏡物件
1. 開啟 GlobalDataClass.h 檔案, 修改如下:
#import <Foundation/Foundation.h>
//@add
#import "SepiaFilter.h"
#import "FalseFilter.h"
#import "ColorFilter.h"
#import "ComboFilter.h"
@interface GlobalDataClass : NSObject
{
//@add: array for storage filterCells
NSMutableArray *filterCellArray;
BOOL isUsingFilter; // 有使用濾鏡?
NSMutableString *filterID; // 濾鏡 ID
//@add: 存放濾鏡物件的字典
NSMutableDictionary *filterDictionary;
}
//@add
@property (nonatomic, strong) NSMutableArray *filterCellArray;
@property (assign) BOOL isUsingFilter;
@property (nonatomic, strong) NSMutableString *filterID;
@property (nonatomic, strong) NSMutableDictionary *filterDictionary;
//@add
+ (GlobalDataClass *)getInstance;
@end
2. 開啟 GlobalDataClass.m 檔案, 修改如下:
....
//@add
@synthesize filterCellArray = _filterCellArray;
@synthesize isUsingFilter = _isUsingFilter;
@synthesize filterID = _filterID;
@synthesize filterDictionary = _filterDictionary;
....
//@add
- (NSMutableDictionary *)filterDictionary
{
if (_filterDictionary == nil) {
_filterDictionary = [[NSMutableDictionary alloc] init];
[_filterDictionary setObject:[SepiaFilter new] forKey:@"filter0"];
[_filterDictionary setObject:[FalseFilter new] forKey:@"filter1"];
[_filterDictionary setObject:[ColorFilter new] forKey:@"filter2"];
[_filterDictionary setObject:[ComboFilter new] forKey:@"filter3"];
}
return _filterDictionary;
}
....
-----------------------------------------------------------------------------
C. 濾鏡套用
1. 開啟 ViewController.h 檔案, 修改如下:
....
@interface ViewController : GLKViewController <AVCaptureVideoDataOutputSampleBufferDelegate, UITableViewDelegate, UITableViewDataSource>
{
....
GlobalDataClass *dataObj;
// 目前使用的濾鏡物件
FilterBase *currentFilter;
}
....
@property (nonatomic, strong) GlobalDataClass *dataObj;
@property (nonatomic, strong) FilterBase *currentFilter;
....//- (CIImage *)filterTest:(CIImage *)sourceImage;
....
2. 開啟 ViewController.m 檔案, 修改如下:
....
// step 1:
@synthesize dataObj = _dataObj;
@synthesize currentFilter = _currentFilter;
....
// step 2:
//@add:filter Test
/*
- (CIImage *)filterTest:(CIImage *)sourceImage
{
self.coreImageFilter = [CIFilter filterWithName:@"CISepiaTone" keysAndValues:
kCIInputImageKey, sourceImage,
@"inputIntensity", [NSNumber numberWithFloat:0.8], nil];
return [self.coreImageFilter outputImage];
}
*/
....
// step 3:
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
....
//@update
if(self.dataObj.isUsingFilter == YES)
{
//@update: comment it
/*
// 濾鏡功能測試
self.ciImage = [self filterTest:self.ciImage];
// 畫出 "濾鏡範圍" 內的影像(含方向轉變的調整)
[self drawFilteredImage:self.ciImage];
*/
// check if key "filterID" exists:
// objectForKey will return nil if a key doesn't exists.
// for Xcode: 4.6.2 update
if ((self.currentFilter = [self.dataObj.filterDictionary objectForKey:self.dataObj.filterID]))
{
self.ciImage = [self.currentFilter filterImage:self.ciImage];
[self drawFilteredImage:self.ciImage];
}
}
// 最後, 在螢幕上呈現出來.
[self.glContext presentRenderbuffer:GL_RENDERBUFFER];
}
....
// step 4:
- (void)viewDidUnload
{
[super viewDidUnload];
//@add
if ([EAGLContext currentContext] == self.glContext) {
[EAGLContext setCurrentContext:nil];
}
....
self.dataObj = nil;
self.currentFilter = nil;
}
....
-----------------------------------------------------------------------------
D. 編譯並執行:
1. 未套用濾鏡:
2. 套用 "墨魚濾鏡":
3. 套用 "假色濾鏡":
4. 套用 "顏色調節濾鏡":
5. 套用 "複合濾鏡": ("假色濾鏡" 與 "顏色調節濾鏡")
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。