2012年7月24日 星期二

Filter4Cam 實作: 21. 影像方向調整之二

since: 2012/07/24
update: 2012/07/24

reference:
1. The iOS 5 Developer's Cookbook, 3/e

"記錄設備上次的擺放方向" 與 "調整按鈕位置"

A. 說明:
     1. 將移除不再使用的 "設備上一次方向是否為水平擺放" 之變數:
          isPreviousOrientationLandscape, 改成由 lastOrientation 來判斷.

     2. "記錄設備上次的擺放方向", 由於只需要記錄: 直擺, 直擺且上下顛倒, 橫擺朝右
          與橫擺朝左共 4 種情況, 因此會在 shouldAutorotateToInterfaceOrientation:
          方法中處理.   

     3. 在  shouldAutorotateToInterfaceOrientation: 方法中, 無法即時偵測到:
         設備面朝上, 面朝下與未知的情況. 因此會將這三種情況(FaceUp, FaceDown
         與 Unknown) 的偵測, 置於 orientationTransform: 方法內, 以協助在開發的
         過程中除錯. (只有當有套用濾鏡功能時, 才會去呼叫 drawFilteredImage: ,
         因此不放在此方法處理)  

     4. orientationTransform: drawFilteredImage: 方法, 皆會被
         captureOutput:didOutputSampleBuffer:fromConnection: 頻繁地呼叫,
         因此除了螢幕繪製的相關內容之處理, 儘量不要在其中處理其它的事情.

    5. 調整按鈕的基本擺放位置, 將在 shouldAutorotateToInterfaceOrientation:
        方法中作適當處理.

-------------------------------------------------------------------------------

B. 開啟 ViewController.h 檔案, 修改如下:
....
@interface ViewController : GLKViewController <AVCaptureVideoDataOutputSampleBufferDelegate, UITableViewDelegate, UITableViewDataSource>
{
....
    BOOL isUsingFrontCamera; // 目前使用前置鏡頭?
    BOOL isLastFrontCamera; // 上次是前置鏡頭?
    //@add 設備上一次方向是否為水平擺放(向左或向右皆算)
    //BOOL isPreviousOrientationLandscape;
    BOOL applyFilter; // 是否套用濾鏡?
....
}
....
@property (assign) BOOL isUsingFrontCamera;
@property (assign) BOOL isLastFrontCamera;
//@property (assign) BOOL isPreviousOrientationLandscape;
@property (assign) BOOL applyFilter; 
 
....

-------------------------------------------------------------------------------

C. 開啟 ViewController.m 檔案, 修改如下:
....
// step 01:
@synthesize isUsingFrontCamera = _isUsingFrontCamera;
@synthesize isLastFrontCamera = _isLastFrontCamera;
//@synthesize isPreviousOrientationLandscape = _isPreviousOrientationLandscape;
@synthesize applyFilter = _applyFilter;
....

// step02:
- (void)viewDidLoad
{
....
    /*
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    if (orientation == UIDeviceOrientationLandscapeRight ||
        orientation == UIDeviceOrientationLandscapeLeft) {
        self.isPreviousOrientationLandscape = YES;
    }
    else {
        self.isPreviousOrientationLandscape = NO;
    }
    */
....
}
....

// step 03:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    //@add
    GlobalDataClass *dataObj = [GlobalDataClass getInstance];
    CGFloat filterCellRotationAngle; // filterCell Rotation Angle
   
    /*
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
    */
   
    // ############# //
    // A. 設備垂直擺放 //
    // ############# //
    if (interfaceOrientation == UIDeviceOrientationPortrait)
    {
        lastOrientation = Portrait; // 記錄為上次: 直擺
        NSLog(@"lastOrientation = Portrait");
       
        //@update: Tune UI
        [self.filterLensImageView setFrame:CGRectMake(20, 120, 280, 280)];
       
        //@add for Button
        /*
        [self.saveButton setFrame:CGRectMake(10, 420, 66, 40)];
        [self.switchButton setFrame:CGRectMake(87, 420, 66, 40)];
        [self.torchButton setFrame:CGRectMake(164, 420, 66, 40)];
        [self.observerButton setFrame:CGRectMake(241, 420, 66, 40)];
        */
        //@update: 調整按鈕相對於 buttonView 的位置
        [self.buttonView setFrame:CGRectMake(0, 398, 320, 82)];
        [self.saveButton setFrame:CGRectMake(10, 22, 66, 40)];
        [self.switchButton setFrame:CGRectMake(87, 22, 66, 40)];
        [self.torchButton setFrame:CGRectMake(164, 22, 66, 40)];
        [self.observerButton setFrame:CGRectMake(241, 22, 66, 40)];
               
        //@update: Tune for Orientation
        self.filterListTableView.transform = CGAffineTransformMakeRotation(-M_PI * 2.0);
        [self.filterListTableView setFrame:CGRectMake(0, 0, self.view.frame.size.width, kOverlayTableViewRowHeight)];
       
        filterCellRotationAngle = M_PI * 0.5;
    }
    // #################### //
    // B. 設備垂直 180 度擺放 //
    // #################### //
    else if (interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)
    {       
        lastOrientation = PortraitUpsideDown; // 記錄為上次: 直擺, 上下顛倒
        NSLog(@"lastOrientation = PortraitUpsideDown");
       
        //@update: Tune UI
        [self.filterLensImageView setFrame:CGRectMake(20, 120, 280, 280)];
       
        //@add for Button
        /*
        [self.saveButton setFrame:CGRectMake(10, 420, 66, 40)];
        [self.switchButton setFrame:CGRectMake(87, 420, 66, 40)];
        [self.torchButton setFrame:CGRectMake(164, 420, 66, 40)];
        [self.observerButton setFrame:CGRectMake(241, 420, 66, 40)];
        */
        //@update: 調整按鈕相對於 buttonView 的位置
        [self.buttonView setFrame:CGRectMake(0, 398, 320, 82)];
        [self.saveButton setFrame:CGRectMake(10, 22, 66, 40)];
        [self.switchButton setFrame:CGRectMake(87, 22, 66, 40)];
        [self.torchButton setFrame:CGRectMake(164, 22, 66, 40)];
        [self.observerButton setFrame:CGRectMake(241, 22, 66, 40)];
       
        //@update: Tune for Orientation
        self.filterListTableView.transform = CGAffineTransformMakeRotation(-M_PI * 2.0);
        [self.filterListTableView setFrame:CGRectMake(0, 0, self.view.frame.size.width, kOverlayTableViewRowHeight)];
       
        filterCellRotationAngle = M_PI * 0.5;
    }
    // ################# //
    // C. 設備水平向右擺放 //
    // ################# //
    else if (interfaceOrientation == UIDeviceOrientationLandscapeRight)
    {     
        lastOrientation = LandscapeRight; // 記錄為上次: 橫擺朝右
        NSLog(@"lastOrientation = LandscapeRight");
       
        //@update: Tune UI
        [self.filterLensImageView setFrame:CGRectMake(120, 20, 280, 280)];
       
        //@add for Button
        /*
        [self.saveButton setFrame:CGRectMake(406, 32, 66, 40)];
        [self.switchButton setFrame:CGRectMake(406, 104, 66, 40)];
        [self.torchButton setFrame:CGRectMake(406, 176, 66, 40)];
        [self.observerButton setFrame:CGRectMake(406, 248, 66, 40)];
        */
        //@update: 調整按鈕相對於 buttonView 的位置
        [self.buttonView setFrame:CGRectMake(398, 22, 82, 278)];
        [self.saveButton setFrame:CGRectMake(8, 10, 66, 40)];
        [self.switchButton setFrame:CGRectMake(8, 82, 66, 40)];
        [self.torchButton setFrame:CGRectMake(8, 154, 66, 40)];
        [self.observerButton setFrame:CGRectMake(8, 226, 66, 40)];
       
        //@update: Tune for Orientation
        self.filterListTableView.transform = CGAffineTransformMakeRotation(M_PI * 0.5);
        [self.filterListTableView setFrame:CGRectMake(0, 0, kOverlayTableViewRowHeight, self.view.frame.size.width)];
       
        filterCellRotationAngle = 0.0;
    }
    // ################# //
    // D. 設備水平向左擺放 //
    // ################# //
    else if (interfaceOrientation == UIDeviceOrientationLandscapeLeft)
    {  
        lastOrientation = LandscapeLeft; // 記錄為上次: 橫擺朝左
        NSLog(@"lastOrientation = LandscapeLeft");
       
        //@update: Tune UI
        [self.filterLensImageView setFrame:CGRectMake(120, 20, 280, 280)];
       
        //@add for Button
        /*
        [self.saveButton setFrame:CGRectMake(406, 32, 66, 40)];
        [self.switchButton setFrame:CGRectMake(406, 104, 66, 40)];
        [self.torchButton setFrame:CGRectMake(406, 176, 66, 40)];
        [self.observerButton setFrame:CGRectMake(406, 248, 66, 40)];
        */
        //@update: 調整按鈕相對於 buttonView 的位置
        [self.buttonView setFrame:CGRectMake(398, 22, 82, 278)];
        [self.saveButton setFrame:CGRectMake(8, 10, 66, 40)];
        [self.switchButton setFrame:CGRectMake(8, 82, 66, 40)];
        [self.torchButton setFrame:CGRectMake(8, 154, 66, 40)];
        [self.observerButton setFrame:CGRectMake(8, 226, 66, 40)];       
       
        //@update: Tune for Orientation
        self.filterListTableView.transform = CGAffineTransformMakeRotation(M_PI * 0.5);
        [self.filterListTableView setFrame:CGRectMake(0, 0, kOverlayTableViewRowHeight, self.view.frame.size.width)];
       
        filterCellRotationAngle = 0.0;
    }
    // ################################# //
    // E. 其它: FaceUp, FaceDown, Unknown //
    // ################################## //
    else
    {
        // 1. 在此, 不記錄上一次設備的方向
        // 2. 在此無法即時偵測到其它情況:
        //    UIDeviceOrientationFaceUp, UIDeviceOrientationFaceDown,
        //    UIDeviceOrientationUnknown
       
        //@update: Tune UI
        [self.filterLensImageView setFrame:CGRectMake(120, 20, 280, 280)];
       
        //@add for Button
        /*
        [self.saveButton setFrame:CGRectMake(406, 32, 66, 40)];
        [self.switchButton setFrame:CGRectMake(406, 104, 66, 40)];
        [self.torchButton setFrame:CGRectMake(406, 176, 66, 40)];
        [self.observerButton setFrame:CGRectMake(406, 248, 66, 40)];
        */
        //@update: 調整按鈕相對於 buttonView 的位置
        [self.buttonView setFrame:CGRectMake(398, 22, 82, 278)];
        [self.saveButton setFrame:CGRectMake(8, 10, 66, 40)];
        [self.switchButton setFrame:CGRectMake(8, 82, 66, 40)];
        [self.torchButton setFrame:CGRectMake(8, 154, 66, 40)];
        [self.observerButton setFrame:CGRectMake(8, 226, 66, 40)];
       
        //@update: Tune for Orientation
        self.filterListTableView.transform = CGAffineTransformMakeRotation(M_PI * 0.5);
        [self.filterListTableView setFrame:CGRectMake(0, 0, self.view.frame.size.width, kOverlayTableViewRowHeight)];
               
        filterCellRotationAngle = M_PI * 0.5;
    }
   
    //@add
    if (dataObj.filterCellArray.count > 0) {
        for (FilterCell* filterCell in dataObj.filterCellArray) {
            filterCell.transform = CGAffineTransformMakeRotation(filterCellRotationAngle);
        }
    }
   
    return YES;

}
....

// step04:
- (void)drawFilteredImage:(CIImage *)sourceImage
{
....
    // 設備垂直擺放
    if (orientation == UIDeviceOrientationPortrait)
    {
        //self.isPreviousOrientationLandscape = NO;
        ....
    }
    // 設備垂直 180 度擺放
    else if (orientation == UIDeviceOrientationPortraitUpsideDown)
   {
        //self.isPreviousOrientationLandscape = NO;
....
    }
    // 設備水平向右擺放
    else if (orientation == UIDeviceOrientationLandscapeRight)
    {
        //self.isPreviousOrientationLandscape = YES;
        ....
    }
    // 設備水平向左擺放(最穩定)
    else if (orientation == UIDeviceOrientationLandscapeLeft)
    {
        //self.isPreviousOrientationLandscape = YES;
....
    }
    // 其它 (UIDeviceOrientationFaceUp, UIDeviceOrientationFaceDown,
    //           UIDeviceOrientationUnknown)
    else
    {   
        // 上一次設備為水平擺放
        // if (self.isPreviousOrientationLandscape == YES)
        if (lastOrientation == LandscapeRight || lastOrientation == LandscapeLeft)
       {
           ....
        }
        //@add:上一次設備為垂直擺放
        else
       {
            ....
        }
    }
}

沒有留言:

張貼留言

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