update: 2012/02/28
reference: 1. I touchs: Filter4Cam 學習之 Getting Raw Video Data
2. I touchs: Filter4Cam 學習之 Saving a Photo
A. 畫出原始影像內容
1. 開啓 ViewController.m 檔案, 修改如下:
....
#pragma mark Implementation Delegate Method
//@add implementation method for <AVCaptureVideoDataOutputSampleBufferDelegate>
// 將接收到由傳送者(delivers)所回傳(callback) 的原始像素資料(raw pixel data).
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
// 將取得的 sampleBuffer 轉成 CVPixelBuffer
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
// 接著, 將 CVPixelBuffer 利用 Core Image 的初始化方法再轉成 CIImage.
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
// 然後使用 CIContext 物件將其內容畫到 render buffer
[self.coreImageContext drawImage:ciImage atPoint:CGPointZero fromRect:[ciImage extent]];
// 最後, 在螢幕上呈現出來.
[self.glContext presentRenderbuffer:GL_RENDERBUFFER];
}
....
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//@add:helper Test
[self helperTest];
//@add: establish Render
[self establishRender];
//@add: establishCamera
[self establishCamera:kCameraBack];
//@add: startRunning
[self startRunningSession];
}
---------------------------------------------------------------------------------------------
B. 調整方向的轉變
1. 開啓 Filter4CamHelper.h 檔案, 修改如下:
#import <Foundation/Foundation.h>
//@add
#import <AVFoundation/AVFoundation.h>
#import <CoreImage/CoreImage.h>
....
//@add for Utility Tools
+ (CIImage *)orientationTransform:(CIImage *)sourceImage; // 方向轉變的調整
@end
2. 開啓 Filter4CamHelper.m 檔案, 修改如下:
....
#pragma mark Utility Tools
//@add:方向轉變的調整
+ (CIImage *)orientationTransform:(CIImage *)sourceImage
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
CGAffineTransform affineTransform; // 仿射轉換
if (orientation == UIDeviceOrientationPortrait)
{
affineTransform = CGAffineTransformMakeRotation(-M_PI / 2);
}
else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
affineTransform = CGAffineTransformMakeRotation(M_PI / 2);
}
else if (orientation == UIDeviceOrientationLandscapeRight) {
affineTransform = CGAffineTransformMakeRotation(M_PI);
}
else {
affineTransform = CGAffineTransformMakeRotation(0);
}
return [sourceImage imageByApplyingTransform:affineTransform];
}
@end
3. 開啓 ViewController.m 檔案, 修改如下:
....
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
// 將取得的 sampleBuffer 轉成 CVPixelBuffer
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
// 接著, 將 CVPixelBuffer 利用 Core Image 的初始化方法再轉成 CIImage.
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
//@add:方向轉變的調整
ciImage = [Filter4CamHelper orientationTransform:ciImage];
// 然後使用 CIContext 物件將其內容畫到 render buffer
[self.coreImageContext drawImage:ciImage atPoint:CGPointZero fromRect:[ciImage extent]];
// 最後, 在螢幕上呈現出來.
[self.glContext presentRenderbuffer:GL_RENDERBUFFER];
}
....
4. 編譯並執行:
說明: 目前當 iOS 設備方向轉變時, 會出現以下的錯誤訊息: (以後再處理)
Failed to make complete framebuffer object 8cd6CoreImage: EAGLContext framebuffer or renderbuffer incorrectly configured!
---------------------------------------------------------------------------------------------
C. 濾鏡測試
1. 開啓 ViewController.h 檔案, 修改如下:
....
//@add for test
- (void)helperTest;
- (CIImage *)filterTest:(CIImage *)sourceImage;
@end
2. 開啓 ViewController.m 檔案, 修改如下:
....
#pragma mark Test
....
//@add
- (CIImage *)filterTest:(CIImage *)sourceImage
{
CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" keysAndValues:
kCIInputImageKey, sourceImage,
@"inputIntensity", [NSNumber numberWithFloat:0.8], nil];
return [filter outputImage];
}
....
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
// 將取得的 sampleBuffer 轉成 CVPixelBuffer
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
// 接著, 將 CVPixelBuffer 利用 Core Image 的初始化方法再轉成 CIImage.
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
//@add:濾鏡測試
ciImage = [self filterTest:ciImage];
//@add:方向轉變的調整
ciImage = [Filter4CamHelper orientationTransform:ciImage];
// 然後使用 CIContext 物件將其內容畫到 render buffer
[self.coreImageContext drawImage:ciImage atPoint:CGPointZero fromRect:[ciImage extent]];
// 最後, 在螢幕上呈現出來.
[self.glContext presentRenderbuffer:GL_RENDERBUFFER];
}
....
3. 編譯並執行