2012年2月28日 星期二

Filter4Cam 實作: 5. 畫出原始影像內容

since: 2012/02/28
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 {
   
    //@TODO
    // 將取得的 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 8cd6
            CoreImage: 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. 編譯並執行

沒有留言:

張貼留言

注意:只有此網誌的成員可以留言。