update: 2012/07/25
reference:
1. The iOS 5 Developer's Cookbook, 3/e
拍照
A. 說明:
1. 要產生的圖片, 不需要再次從 filter 取得 CIImage 的輸出:
self.ciImage = [self.coreImageFilter outputImage], 直接使用 self.ciImage 即可,
因為 self.ciImage 會在之前的處理過程中, 採用原始影像或套用濾鏡.
2. ALAssetOrientation 的值, 可有以下 8 種:
ALAssetOrientationUp;
ALAssetOrientationUpMirrored;
ALAssetOrientationDown;
ALAssetOrientationDownMirrored;
ALAssetOrientationRight;
ALAssetOrientationRightMirrored;
ALAssetOrientationLeft;
ALAssetOrientationLeftMirrored;
3. "擷取的濾鏡影像範圍"(fromRect:) 與 drawFilteredImage: 方法中,
drawImage:inRect:fromRect: 裡的 fromRect: 設定值相同
4. 使用 ALAssetsLibrary 將 CGImageRef 儲存到相簿裡的函式有二個:
a. writeImageToSavedPhotosAlbum:metadata:completionBlock:
b. writeImageToSavedPhotosAlbum:orientation:completionBlock:
5. 依照 "設備擺放方向", "前後置鏡頭" 與 "設備上次擺放方向" 來調整
產生圖片的方向.
-----------------------------------------------------------------------------
B. 開啟 ViewController.m 檔案, 修改如下:
....
//@update: "拍照": 只截取濾鏡範圍的影像
- (void)savePhoto
{
// 產生 CGImageRef
CGImageRef cgImage = nil;
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
ALAssetOrientation ALAOrientation = ALAssetOrientationUp;
// ################################################# //
// A. 設備擺放方向為: "垂直" 或 "垂直 180 度" 或 "水平向右" 或 "水平向左" //
// ################################################# //
if (orientation == UIDeviceOrientationPortrait ||
orientation == UIDeviceOrientationPortraitUpsideDown ||
orientation == UIDeviceOrientationLandscapeRight ||
orientation == UIDeviceOrientationLandscapeLeft)
{
///////////////////////////////////////
// 1. 擷取濾鏡影像範圍
//
// 設備垂直擺放
if (orientation == UIDeviceOrientationPortrait)
{
cgImage = [self.coreImageContext createCGImage:self.ciImage fromRect:CGRectMake(23, -557.5, 274, 274)];
}
// 設備垂直 180 度擺放
else if (orientation == UIDeviceOrientationPortraitUpsideDown)
{
cgImage = [self.coreImageContext createCGImage:self.ciImage fromRect:CGRectMake(-458.5, 83, 274, 274)];
}
// "設備水平向右擺放" 或 "設備水平向左擺放"
else if (orientation == UIDeviceOrientationLandscapeRight ||
orientation == UIDeviceOrientationLandscapeLeft)
{
cgImage = [self.coreImageContext createCGImage:self.ciImage fromRect:CGRectMake(123.5, 23.5, 274, 274)];
}
///////////////////////////////////////
// 2. "前置鏡頭" 影像方向
//
// 前置鏡頭
if (self.isUsingFrontCamera)
{
// 設備水平向左擺放
if (orientation == UIDeviceOrientationLandscapeLeft)
{
ALAOrientation = ALAssetOrientationDownMirrored;
}
// 其它: 垂直, 垂直 180 度, 水平向右
else
{
ALAOrientation = ALAssetOrientationUpMirrored;
}
// 將 CGImageRef 儲存到相簿裡
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:cgImage orientation:ALAOrientation
completionBlock:^(NSURL *assetURL, NSError *error) {
// 釋放 CGImage, 這是一個 callback block, 當處理完畢時才會觸發.
CGImageRelease(cgImage);
}];
}
///////////////////////////////////////
// 3. "後置鏡頭" 影像方向
//
// 後置鏡頭
else
{
// 設備水平向右擺放
if (orientation == UIDeviceOrientationLandscapeRight)
{
ALAOrientation = ALAssetOrientationDown;
// 將 CGImageRef 儲存到相簿裡
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:cgImage orientation:ALAOrientation
completionBlock:^(NSURL *assetURL, NSError *error) {
// 釋放 CGImage, 這是一個 callback block, 當處理完畢時才會觸發.
CGImageRelease(cgImage);
}];
}
// 其它: 垂直, 垂直 180 度, 水平向左
else {
// 將 CGImageRef 儲存到相簿裡
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:cgImage
metadata:[self.ciImage properties]
completionBlock:^(NSURL *assetURL, NSError *error) {
// 釋放 CGImage, 這是一個 callback block, 當處理完畢時才會觸發.
CGImageRelease(cgImage);
}];
}
}
}
// ############################### //
// B. 設備擺放方向為: "朝上" 或 "朝下" 或 "未知" //
// ############################### //
else if(orientation == UIDeviceOrientationFaceUp ||
orientation == UIDeviceOrientationFaceDown ||
orientation == UIDeviceOrientationUnknown)
{
///////////////////////////////////////
// 1. 擷取濾鏡影像範圍
//
// 上次為直擺
if (lastOrientation == Portrait)
{
cgImage = [self.coreImageContext createCGImage:self.ciImage fromRect:CGRectMake(23, -557.5, 274, 274)];
}
// 上次為直擺且上下顛倒
else if (lastOrientation == PortraitUpsideDown)
{
cgImage = [self.coreImageContext createCGImage:self.ciImage fromRect:CGRectMake(-458.5, 83.5, 274, 274)];
}
// 上次為 "橫擺朝右" 或上次為 "橫擺朝左"
else if (lastOrientation == LandscapeRight ||
lastOrientation == LandscapeLeft)
{
cgImage = [self.coreImageContext createCGImage:self.ciImage fromRect:CGRectMake(123.5, 23.5, 274, 274)];
}
else
{
NSLog(@"savePhoto: orientation = FaceUp/FaceDown/Unknown, lastOrientation not defined!");
}
///////////////////////////////////////
// 2. "前置鏡頭" 影像方向
//
if (self.isUsingFrontCamera)
{
// 上次為 "橫擺朝左"
if (lastOrientation == LandscapeLeft)
{
ALAOrientation = ALAssetOrientationDownMirrored;
}
// 其它: 上次為 "直擺", "直擺且上下顛倒" 或 "橫擺朝右"
else
{
ALAOrientation = ALAssetOrientationUpMirrored;
}
// 將 CGImageRef 儲存到相簿裡
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:cgImage orientation:ALAOrientation
completionBlock:^(NSURL *assetURL, NSError *error) {
// 釋放 CGImage, 這是一個 callback block, 當處理完畢時才會觸發.
CGImageRelease(cgImage);
}];
}
///////////////////////////////////////
// 3. "後置鏡頭" 影像方向
//
// 後置鏡頭
else
{
// 上次為 "橫擺朝右"
if (lastOrientation == LandscapeRight)
{
ALAOrientation = ALAssetOrientationDown;
// 將 CGImageRef 儲存到相簿裡
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:cgImage orientation:ALAOrientation
completionBlock:^(NSURL *assetURL, NSError *error) {
// 釋放 CGImage, 這是一個 callback block, 當處理完畢時才會觸發.
CGImageRelease(cgImage);
}];
}
else {
// 將 CGImageRef 儲存到相簿裡
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeImageToSavedPhotosAlbum:cgImage
metadata:[self.ciImage properties]
completionBlock:^(NSURL *assetURL, NSError *error) {
// 釋放 CGImage, 這是一個 callback block, 當處理完畢時才會觸發.
CGImageRelease(cgImage);
}];
}
}
}
else
{
NSLog(@"savePhoto: No orientation match!");
}
}
....
-----------------------------------------------------------------------------
C. 編譯並執行:
1. 先將 buttonView 的 backgroundColor 註解後, 再編譯並執行.
// ViewController.m
....
// 用來放所有按鈕的 View
- (UIView *)buttonView
{
if (_buttonView == nil) {
_buttonView = [[UIView alloc] init];
//@測試使用
//_buttonView.backgroundColor = [UIColor redColor];
}
return _buttonView;
}
....
2. 設備水平向右擺放:
(相機鏡頭在右後方, 功能按鈕遠離相機鏡頭位置)
沒有留言:
張貼留言
注意:只有此網誌的成員可以留言。