since: 2012/07/24
update: 2012/07/24
reference:
1. The iOS 5 Developer's Cookbook, 3/e
前置準備
A. 說明
1. 如果使用圖像挑選器(image picker), 系統會自動處理跟方向有關的問題.
在這個專案裡是使用 AVFoundation 來存取相機, 因此必須自行根據不同的
情況(使用前置或後置相機, 裝置擺放方向) 來處理影像緩衝區裡的原始資料,
以使影像的呈現保持正向.
2. 這個專案沒有使用到 AVFoundation 的 AVCaptureVideoPreviewLayer 類別,
它提供了即時圖像預覽的圖層, 可以將其嵌入到視圖裡.
3. 由於整個調整的內容範圍較廣, 會等到這一系列的調整都完成後, 再進行編譯.
4. 關於 "影像方向調整" 這部分, 使用了土法煉鋼的方式(費時費力),
修改得有點複雜了, 僅供參考. (希望以後能有較好的解決方式)
----------------------------------------------------------------------------------------
B. 新增: radians(弧度) 與 degrees(角度) 轉換函式
1. 開啟 Filter4CamHelper.h 檔案, 修改如下:
....
@end
// Convert between radians(弧度) and degrees(角度)
CGFloat DegreesToRadians(CGFloat degrees);
CGFloat RadiansToDegrees(CGFloat radians);
****************************************
2. 開啟 Filter4CamHelper.m 檔案, 修改如下:
....
@end
//@add: Convert between radians(弧度) and degrees(角度)
CGFloat DegreesToRadians(CGFloat degrees)
{
return degrees * M_PI / 180;
};
CGFloat RadiansToDegrees(CGFloat radians)
{
return radians * 180 / M_PI;
};
----------------------------------------------------------------------------------------
C. 定義: 儲存 "設備上次的擺放方向"
開啟 ConstantDefined.h 檔案, 修改如下:
....
////////////////////////////////////////////////////////////////////
// 設備上次的擺放方向(目前不記錄:FaceUp, FaceDown, 與 Unknown)
//
//
enum kLastOrientation
{
Portrait, // 直擺
PortraitUpsideDown, // 直擺, 上下顛倒
LandscapeRight, // 橫擺朝右
LandscapeLeft, // 橫擺朝左
FaceUp, // 面朝上
FaceDown, // 面朝下
Unknown // 未知
};
#endif
----------------------------------------------------------------------------------------
D. 修改函式名稱
1. 說明:
在 ViewController.m 中的
captureOutput: didOutputSampleBuffer:fromConnection: 方法裡,
呼叫了 filterOrientationTransform: 來將 "濾鏡範圍" 內的影像內容
畫到 render buffer, 將其函式名稱改成: drawFilteredImage: 以符實情.
****************************************
2. 開啟 ViewController.h 檔案, 修改如下:
....
//@add for orientation Transform
- (CIImage *)orientationTransform:(CIImage *)sourceImage; // 轉換原始影像的方向
//- (void)filterOrientationTransform:(CIImage *)sourceImage; // 方向轉變的調整
- (void)drawFilteredImage:(CIImage *)filteredImage; // 畫出 "濾鏡範圍" 內的影像(含方向轉變的調整)
....
****************************************
3. 開啟 ViewController.m 檔案, 修改如下:
....
// step 1:
//@add for filter Orientation Transform (方向轉變的調整)
//- (void)filterOrientationTransform:(CIImage *)sourceImage
// 畫出 "濾鏡範圍" 內的影像(含方向轉變的調整)
- (void)drawFilteredImage:(CIImage *)filteredImage
....
// step 2:
....
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
....
//[self filterOrientationTransform:ciImage];
// 畫出 "濾鏡範圍" 內的影像(含方向轉變的調整)
[self drawFilteredImage:self.ciImage];
....
}
....
----------------------------------------------------------------------------------------
E. 新增: 記錄上次是否為前置鏡頭之變數
1. 開啟 ViewController.h 檔案, 修改如下:
....
@interface ViewController : GLKViewController <AVCaptureVideoDataOutputSampleBufferDelegate, UITableViewDelegate, UITableViewDataSource>
{
....
BOOL isUsingFrontCamera; // 目前使用前置鏡頭?
BOOL isLastFrontCamera; // 上次是前置鏡頭?
....
// 設備上次的擺放方向(目前不記錄:FaceUp, FaceDown, 與 Unknown)
//
// Portrait, // 直擺
// PortraitUpsideDown, // 直擺, 上下顛倒
// LandscapeRight, // 橫擺朝右
// LandscapeLeft, // 橫擺朝左
// FaceUp, // 面朝上
// FaceDown, // 面朝下
// Unknown // 未知
enum kLastOrientation lastOrientation;
}
....
@property (assign) BOOL isUsingFrontCamera;
@property (assign) BOOL isLastFrontCamera;
....
****************************************
2. 開啟 ViewController.m 檔案, 修改如下:
....// step 1:
@synthesize isUsingFrontCamera = _isUsingFrontCamera;
@synthesize isLastFrontCamera = _isLastFrontCamera;
....
// step 2:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//@add
self.applyFilter = NO;
self.isUsingFrontCamera = NO; // 預設為後置鏡頭
self.isLastFrontCamera = NO; // 預設上次為後置鏡頭
lastOrientation = Unknown; // 設備上次的擺放方向: 未知
....
}
....
----------------------------------------------------------------------------------------
F. 新增: 用來放所有按鈕的 View
1. 開啟 ViewController.h 檔案, 修改如下:
....
@interface ViewController : GLKViewController <AVCaptureVideoDataOutputSampleBufferDelegate, UITableViewDelegate, UITableViewDataSource>
{
....
//@add for Camera Overlay UI
UIImageView *filterLensImageView;
UITableView *filterListTableView;
UIView *buttonView; // 用來放所有按鈕的 View
UIButton *saveButton; // "拍照" 按鈕
UIButton *switchButton; // "鏡頭切換" 按鈕
UIButton *torchButton; // "閃光燈切換" 按鈕
UIButton *observerButton; // "觀察者模式" 按鈕
....
}
....
//@add for Camera Overlay UI
@property (nonatomic, strong) UIImageView *filterLensImageView;
@property (nonatomic, strong) UITableView *filterListTableView;
@property (nonatomic, strong) UIView *buttonView;
@property (nonatomic, strong) UIButton *saveButton;
@property (nonatomic, strong) UIButton *switchButton;
@property (nonatomic, strong) UIButton *torchButton;
@property (nonatomic, strong) UIButton *observerButton;
....
****************************************
2. 開啟 ViewController.m 檔案, 修改如下:
....
// step01:
//@add for Camera Overlay UI
@synthesize filterLensImageView = _filterLensImageView;
@synthesize filterListTableView = _filterListTableView;
@synthesize buttonView = _buttonView;
@synthesize saveButton = _saveButton;
@synthesize switchButton = _switchButton;
@synthesize torchButton = _torchButton;
@synthesize observerButton = _observerButton;
....
// step02:
#pragma mark Getter
....
// 用來放所有按鈕的 View
- (UIView *)buttonView
{
if (_buttonView == nil) {
_buttonView = [[UIView alloc] init];
_buttonView.backgroundColor = [UIColor redColor]; // 測試使用
}
return _buttonView;
}
....
// step03:
//@add for setting camera Overlay
- (void)cameraOverlay
{
....
/*
[self.view addSubview:self.saveButton];
[self.view addSubview:self.switchButton];
[self.view addSubview:self.torchButton];
[self.view addSubview:self.observerButton];
*/
//@update: add buttonView
[self.view addSubview:self.buttonView];
[self.buttonView addSubview:self.saveButton];
[self.buttonView addSubview:self.switchButton];
[self.buttonView addSubview:self.torchButton];
[self.buttonView addSubview:self.observerButton];
....
}
....
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。