├── HanCamera
├── snap.png
├── xxl.jpg
├── flashlightAuto.png
├── flashlightOff.png
├── flashlightOn.png
├── iTunesArtwork.png
├── switchCamera.png
├── swtichCamera.png
├── EditManager.m
├── EditManager.h
├── AppDelegate.h
├── main.m
├── EditViewController.h
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── ViewController.h
├── Info.plist
├── AppDelegate.m
├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
├── EditViewController.m
└── ViewController.m
├── HanCamera.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── hanchang.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── WorkspaceSettings.xcsettings
├── xcuserdata
│ └── hanchang.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── HanCamera.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
└── HanCameraTests
├── Info.plist
└── HanCameraTests.m
/HanCamera/snap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/snap.png
--------------------------------------------------------------------------------
/HanCamera/xxl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/xxl.jpg
--------------------------------------------------------------------------------
/HanCamera/flashlightAuto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/flashlightAuto.png
--------------------------------------------------------------------------------
/HanCamera/flashlightOff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/flashlightOff.png
--------------------------------------------------------------------------------
/HanCamera/flashlightOn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/flashlightOn.png
--------------------------------------------------------------------------------
/HanCamera/iTunesArtwork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/iTunesArtwork.png
--------------------------------------------------------------------------------
/HanCamera/switchCamera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/switchCamera.png
--------------------------------------------------------------------------------
/HanCamera/swtichCamera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera/swtichCamera.png
--------------------------------------------------------------------------------
/HanCamera.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HanCamera.xcodeproj/project.xcworkspace/xcuserdata/hanchang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mirhan/HanCamera/HEAD/HanCamera.xcodeproj/project.xcworkspace/xcuserdata/hanchang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/HanCamera/EditManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // EditManager.m
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/10.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import "EditManager.h"
10 |
11 | @implementation EditManager
12 | @synthesize imageToEdit;
13 | @end
14 |
--------------------------------------------------------------------------------
/HanCamera/EditManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // EditManager.h
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/10.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface EditManager : NSObject
13 | @property UIImage *imageToEdit;
14 | @end
15 |
--------------------------------------------------------------------------------
/HanCamera/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/6.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/HanCamera/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/6.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/HanCamera.xcodeproj/project.xcworkspace/xcuserdata/hanchang.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/HanCamera/EditViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // EditViewController.h
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/10.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface EditViewController : UIViewController
12 | @property UIImage* originalImage;
13 | @property UIImage* image;
14 | @property(nonatomic,retain) NSArray *pickerViewData;
15 | + (UIImage *) effectImage: (UIImage *)uIImage byFilterName:(NSString *)filterName;
16 | @end
17 |
--------------------------------------------------------------------------------
/HanCamera.xcodeproj/xcuserdata/hanchang.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | HanCamera.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 31E2ED311A0B1B78008FB715
16 |
17 | primary
18 |
19 |
20 | 31E2ED4A1A0B1B78008FB715
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/HanCamera/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/HanCameraTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/HanCamera/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/6.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | typedef enum : NSUInteger {
13 | hcCameraMode9to16,
14 | hcCameraMode1to1,
15 | hcCameraMode3to4,
16 | } hcCameraMode;
17 |
18 | @interface ViewController : UIViewController
19 |
20 | @property (nonatomic,retain) AVCaptureSession *session;
21 | @property AVCaptureStillImageOutput *imageOutput;
22 | @property AVCaptureVideoPreviewLayer *previewSubLayer;
23 | @property hcCameraMode cameraMode;
24 |
25 | #pragma mark Actions
26 | - (IBAction)clickSnapImageButton:(id)sender;
27 | - (IBAction)clickCameraRollButton:(id)sender;
28 | - (IBAction)clickSwitchCameraButton:(id)sender;
29 | - (IBAction)clickFlashlightButton:(id)sender;
30 | - (IBAction)clickProportionButton:(id)sender;
31 |
32 | @end
33 |
34 |
--------------------------------------------------------------------------------
/HanCameraTests/HanCameraTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // HanCameraTests.m
3 | // HanCameraTests
4 | //
5 | // Created by 韩畅 on 14/11/6.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface HanCameraTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation HanCameraTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/HanCamera/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIStatusBarHidden
6 |
7 | UIViewControllerBasedStatusBarAppearance
8 |
9 | CFBundleIconFiles
10 |
11 | iTunesArtwork
12 |
13 | CFBundleDevelopmentRegion
14 | en
15 | CFBundleExecutable
16 | $(EXECUTABLE_NAME)
17 | CFBundleIdentifier
18 | com.example.$(PRODUCT_NAME:rfc1034identifier)
19 | CFBundleInfoDictionaryVersion
20 | 6.0
21 | CFBundleName
22 | $(PRODUCT_NAME)
23 | CFBundlePackageType
24 | APPL
25 | CFBundleShortVersionString
26 | 1.0
27 | CFBundleSignature
28 | ????
29 | CFBundleVersion
30 | 1
31 | LSRequiresIPhoneOS
32 |
33 | UILaunchStoryboardName
34 | LaunchScreen
35 | UIMainStoryboardFile
36 | Main
37 | UIRequiredDeviceCapabilities
38 |
39 | armv7
40 |
41 | UISupportedInterfaceOrientations
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationLandscapeLeft
45 | UIInterfaceOrientationLandscapeRight
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/HanCamera/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/6.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/HanCamera.xcodeproj/xcuserdata/hanchang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
18 |
19 |
20 |
22 |
34 |
35 |
36 |
38 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/HanCamera/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/HanCamera.xcodeproj/xcuserdata/hanchang.xcuserdatad/xcschemes/HanCamera.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/HanCamera/EditViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // EditViewController.m
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/10.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import "EditViewController.h"
10 |
11 | @interface EditViewController ()
12 | @property (weak, nonatomic) IBOutlet UIImageView *editImageView;
13 | @property (weak, nonatomic) IBOutlet UIPickerView *effectPickerView;
14 |
15 | @end
16 |
17 | @implementation EditViewController
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 |
22 | self.editImageView.contentMode = UIViewContentModeScaleAspectFit;
23 | self.editImageView.userInteractionEnabled = YES;
24 |
25 | self.effectPickerView.delegate = (id)self;
26 | self.editImageView.image = self.image;
27 |
28 | // 似乎只有一部分可以在 iOS 中使用
29 | NSArray *array=[[NSArray alloc] initWithObjects:
30 | @"None",
31 | // @"CIColorCrossPolynomial",
32 | // @"CIColorCube",
33 | // @"CIColorCubeWithColorSpace",
34 | // @"CIColorInvert",
35 | // @"CIColorMap",
36 | // @"CIColorMonochrome",
37 | // @"CIColorPosterize",
38 | @"CIFalseColor",
39 | // @"CIMaskToAlpha",
40 | // @"CIMaximumComponent",
41 | // @"CIMinimumComponent",
42 | @"CIPhotoEffectChrome",
43 | @"CIPhotoEffectFade",
44 | // @"CIPhotoEffectInstant",
45 | // @"CIPhotoEffectMono",
46 | // @"CIPhotoEffectNoir",
47 | // @"CIPhotoEffectProcess",
48 | // @"CIPhotoEffectTonal",
49 | // @"CIPhotoEffectTransfer",
50 | // @"CISepiaTone",
51 | // @"CIVignette",
52 | // @"CIVignetteEffect",
53 | nil];
54 | [self setPickerViewData:array];
55 | }
56 |
57 | -(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
58 | {
59 | return 1;
60 | }
61 |
62 | -(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
63 | {
64 | return [[self pickerViewData] count];
65 | }
66 |
67 | -(UIView *)pickerView:(UIPickerView *)pickerView
68 | titleForRow:(NSInteger)row
69 | forComponent:(NSInteger)component
70 | {
71 |
72 | return [[self pickerViewData] objectAtIndex:row];
73 | }
74 |
75 |
76 | // 选中 pickerview 的某行时会调用该函数。
77 | - (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
78 | NSString *filterName = [[self pickerViewData]objectAtIndex:row];
79 | UIImage *newImage = [EditViewController effectImage:[self originalImage] byFilterName:filterName];
80 |
81 | [self setImage:newImage];
82 | [[self editImageView] setImage:newImage];
83 | }
84 |
85 | // Cancel 按钮
86 | - (IBAction)clickCancelButton:(id)sender {
87 | [self dismissViewControllerAnimated:YES completion:^{
88 | }];
89 | }
90 |
91 | // Done 按钮
92 | - (IBAction)clickDoneButton:(id)sender {
93 | [self dismissViewControllerAnimated:YES completion:^{
94 | }];
95 |
96 | UIImageWriteToSavedPhotosAlbum([self image], self, nil, nil); // TODO 异常处理
97 | }
98 |
99 | - (void)didReceiveMemoryWarning {
100 | [super didReceiveMemoryWarning];
101 | // Dispose of any resources that can be recreated.
102 | }
103 |
104 | // 滤镜
105 | + (UIImage *) effectImage: (UIImage *)uIImage byFilterName:(NSString *)filterName;
106 | {
107 | if ([filterName isEqualToString:@"None"]) {
108 | return uIImage;
109 | }
110 |
111 | UIImage *tempImage = [EditViewController scaleAndRotateImage:uIImage];
112 |
113 | CIContext *context = [CIContext contextWithOptions:nil];
114 |
115 | CIImage *ciImage = [[CIImage alloc] initWithImage:tempImage]; // 解决滤镜后图片方向不对的问题
116 |
117 | CIFilter *filter = [CIFilter filterWithName:filterName];
118 | [filter setValue:ciImage forKey:kCIInputImageKey];
119 |
120 | CIImage *result = [filter valueForKey:kCIOutputImageKey];
121 |
122 | CGRect extent = [result extent];
123 |
124 | CGImageRef cgImage = [context createCGImage:result fromRect:extent];
125 | UIImage *filteredImage = [[UIImage alloc] initWithCGImage:cgImage];
126 | CGImageRelease(cgImage);
127 |
128 | return filteredImage;
129 | }
130 |
131 | // Code from: http://discussions.apple.com/thread.jspa?messageID=7949889
132 | + (UIImage *)scaleAndRotateImage:(UIImage *)image {
133 | int kMaxResolution = 640; // Or whatever
134 |
135 | CGImageRef imgRef = image.CGImage;
136 |
137 | CGFloat width = CGImageGetWidth(imgRef);
138 | CGFloat height = CGImageGetHeight(imgRef);
139 |
140 |
141 | CGAffineTransform transform = CGAffineTransformIdentity;
142 | CGRect bounds = CGRectMake(0, 0, width, height);
143 | if (width > kMaxResolution || height > kMaxResolution) {
144 | CGFloat ratio = width/height;
145 | if (ratio > 1) {
146 | bounds.size.width = kMaxResolution;
147 | bounds.size.height = roundf(bounds.size.width / ratio);
148 | }
149 | else {
150 | bounds.size.height = kMaxResolution;
151 | bounds.size.width = roundf(bounds.size.height * ratio);
152 | }
153 | }
154 |
155 | CGFloat scaleRatio = bounds.size.width / width;
156 | CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
157 | CGFloat boundHeight;
158 | UIImageOrientation orient = image.imageOrientation;
159 | switch(orient) {
160 |
161 | case UIImageOrientationUp: //EXIF = 1
162 | transform = CGAffineTransformIdentity;
163 | break;
164 |
165 | case UIImageOrientationUpMirrored: //EXIF = 2
166 | transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
167 | transform = CGAffineTransformScale(transform, -1.0, 1.0);
168 | break;
169 |
170 | case UIImageOrientationDown: //EXIF = 3
171 | transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
172 | transform = CGAffineTransformRotate(transform, M_PI);
173 | break;
174 |
175 | case UIImageOrientationDownMirrored: //EXIF = 4
176 | transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
177 | transform = CGAffineTransformScale(transform, 1.0, -1.0);
178 | break;
179 |
180 | case UIImageOrientationLeftMirrored: //EXIF = 5
181 | boundHeight = bounds.size.height;
182 | bounds.size.height = bounds.size.width;
183 | bounds.size.width = boundHeight;
184 | transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
185 | transform = CGAffineTransformScale(transform, -1.0, 1.0);
186 | transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
187 | break;
188 |
189 | case UIImageOrientationLeft: //EXIF = 6
190 | boundHeight = bounds.size.height;
191 | bounds.size.height = bounds.size.width;
192 | bounds.size.width = boundHeight;
193 | transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
194 | transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
195 | break;
196 |
197 | case UIImageOrientationRightMirrored: //EXIF = 7
198 | boundHeight = bounds.size.height;
199 | bounds.size.height = bounds.size.width;
200 | bounds.size.width = boundHeight;
201 | transform = CGAffineTransformMakeScale(-1.0, 1.0);
202 | transform = CGAffineTransformRotate(transform, M_PI / 2.0);
203 | break;
204 |
205 | case UIImageOrientationRight: //EXIF = 8
206 | boundHeight = bounds.size.height;
207 | bounds.size.height = bounds.size.width;
208 | bounds.size.width = boundHeight;
209 | transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
210 | transform = CGAffineTransformRotate(transform, M_PI / 2.0);
211 | break;
212 |
213 | default:
214 | [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];
215 |
216 | }
217 |
218 | UIGraphicsBeginImageContext(bounds.size);
219 |
220 | CGContextRef context = UIGraphicsGetCurrentContext();
221 |
222 | if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
223 | CGContextScaleCTM(context, -scaleRatio, scaleRatio);
224 | CGContextTranslateCTM(context, -height, 0);
225 | }
226 | else {
227 | CGContextScaleCTM(context, scaleRatio, -scaleRatio);
228 | CGContextTranslateCTM(context, 0, -height);
229 | }
230 |
231 | CGContextConcatCTM(context, transform);
232 |
233 | CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
234 | UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
235 | UIGraphicsEndImageContext();
236 |
237 | return imageCopy;
238 | }
239 | /*
240 | #pragma mark - Navigation
241 |
242 | // In a storyboard-based application, you will often want to do a little preparation before navigation
243 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
244 | // Get the new view controller using [segue destinationViewController].
245 | // Pass the selected object to the new view controller.
246 | }
247 | */
248 |
249 | @end
250 |
--------------------------------------------------------------------------------
/HanCamera/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
32 |
41 |
49 |
58 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/HanCamera/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // HanCamera
4 | //
5 | // Created by 韩畅 on 14/11/6.
6 | // Copyright (c) 2014年 韩畅. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import "ViewController.h"
13 | #import "EditViewController.h"
14 |
15 | @interface ViewController ()
16 | @property (weak, nonatomic) IBOutlet UIButton *proportionButton;
17 | @property (weak, nonatomic) IBOutlet UIButton *switchCameraButton;
18 | @property (weak, nonatomic) IBOutlet UIButton *snapButton;
19 | @property (weak, nonatomic) IBOutlet UIButton *flashlightButton;
20 | @property (weak, nonatomic) IBOutlet UIView *preview;
21 | @end
22 |
23 | @implementation ViewController
24 |
25 | @synthesize session;
26 | @synthesize imageOutput;
27 | @synthesize cameraMode;
28 |
29 | - (void)viewDidLoad {
30 | [super viewDidLoad];
31 |
32 | [self setCameraMode:hcCameraMode9to16];
33 |
34 | [[[self preview] layer] setBackgroundColor:[[UIColor blackColor]CGColor]];
35 |
36 | // session 连接到 captureDevive
37 | [self setSession:[[AVCaptureSession alloc] init]];
38 |
39 | AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
40 | AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:nil];
41 |
42 | if ([[self session] canAddInput:deviceInput])
43 | [[self session] addInput:deviceInput];
44 |
45 | // 初始化界面按键
46 | [self initViewsOfButtons:captureDevice.flashMode];
47 |
48 | // 预览 session
49 | [self loadPreviewLayer];
50 |
51 | // output
52 | [self setImageOutput:[[AVCaptureStillImageOutput alloc] init]];
53 |
54 | NSDictionary *setting = [[NSDictionary alloc]initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
55 | [[self imageOutput] setOutputSettings:setting];
56 |
57 | [session addOutput:self.imageOutput];
58 |
59 | [[self session] startRunning];
60 | }
61 |
62 | // 预览 session
63 | - (void) loadPreviewLayer {
64 | AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:[self session]];
65 |
66 | CGFloat proportion = [self getPoportionByHcCameraMode:[self cameraMode]];
67 | [previewLayer setFrame:[self getFrameByProportion:proportion]];
68 |
69 | [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
70 |
71 | [[[self preview] layer] setMasksToBounds:YES];
72 | [[[self preview] layer] insertSublayer:previewLayer atIndex:0];
73 | }
74 |
75 | // 根据比例裁剪图片
76 | - (UIImage*) cropImageWithImage:(UIImage*) image proportion:(CGFloat)proportion {
77 |
78 | CGSize newSize = [self sizeWithSize:image.size poportion:proportion];
79 |
80 | CGRect rect = CGRectMake(image.scale * (image.size.height / 2 - newSize.height / 2),
81 | image.scale * (image.size.width / 2 - newSize.width / 2),
82 | image.scale * newSize.height,
83 | image.scale * newSize.width);
84 |
85 | CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
86 | UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation];
87 |
88 | CGImageRelease(imageRef);
89 |
90 | return newImage;
91 | }
92 |
93 | // 按照 size 缩放图片
94 | - (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize;
95 | {
96 | // Create a graphics image context
97 | UIGraphicsBeginImageContext(newSize);
98 |
99 | // Tell the old image to draw in this new context, with the desired
100 | // new size
101 | [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
102 |
103 | // Get the new image from the context
104 | UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
105 |
106 | // End the context
107 | UIGraphicsEndImageContext();
108 |
109 | // Return the new image.
110 | return newImage;
111 | }
112 |
113 | - (void)didReceiveMemoryWarning {
114 | [super didReceiveMemoryWarning];
115 | // Dispose of any resources that can be recreated.
116 | }
117 |
118 | // 拍照按钮
119 | - (IBAction)clickSnapImageButton:(id)sender {
120 |
121 | // 闪光效果
122 | UIView *flashView = [[UIView alloc] initWithFrame:[[self preview] frame]];
123 | [flashView setBackgroundColor:[UIColor blackColor]];
124 | [[[self preview] window] addSubview:flashView];
125 |
126 | [UIView animateWithDuration:.4f
127 | animations:^{
128 | [flashView setAlpha:0.f];
129 | }
130 | completion:^(BOOL finished){
131 | [flashView removeFromSuperview];
132 | }];
133 |
134 | // 获取相机的连接
135 | AVCaptureConnection *connection = nil;
136 | for (AVCaptureConnection *tempConnection in self.imageOutput.connections) {
137 | for (AVCaptureInputPort *port in [tempConnection inputPorts]) {
138 | if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
139 | connection = tempConnection;
140 | break;
141 | }
142 | }
143 | if (connection) {
144 | break;
145 | }
146 | }
147 |
148 | // 保存图片
149 | [self.imageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
150 | NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
151 | UIImage *image = [[UIImage alloc]initWithData:imageData];
152 | // 切割图片
153 | CGFloat proportion = [self getPoportionByHcCameraMode:[self cameraMode]];
154 | image = [self cropImageWithImage:image proportion:proportion];
155 |
156 | [self presentEditViewController:image];
157 | }];
158 | }
159 |
160 | // 图片库按钮
161 | - (IBAction)clickCameraRollButton:(id)sender {
162 |
163 | if ([UIImagePickerController isSourceTypeAvailable:
164 | UIImagePickerControllerSourceTypeSavedPhotosAlbum])
165 | {
166 | UIImagePickerController *imagePicker =
167 | [[UIImagePickerController alloc] init];
168 | imagePicker.delegate = self;
169 | imagePicker.sourceType =
170 | UIImagePickerControllerSourceTypePhotoLibrary;
171 | imagePicker.mediaTypes = [NSArray arrayWithObjects:
172 | (NSString *) kUTTypeImage,
173 | nil];
174 | imagePicker.allowsEditing = NO;
175 | [self presentViewController:imagePicker animated:YES completion:^(void){}];
176 | }
177 | }
178 |
179 | // 图库选中了照片
180 | - (void)imagePickerController: (UIImagePickerController *)picker
181 | didFinishPickingMediaWithInfo: (NSDictionary *)info
182 | {
183 | NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
184 |
185 | [picker dismissViewControllerAnimated:YES completion:^(void){}];
186 |
187 | if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
188 | UIImage *image = [info
189 | objectForKey:UIImagePickerControllerOriginalImage];
190 |
191 | [self presentEditViewController:image];
192 | }
193 | }
194 |
195 | - (void)presentEditViewController:(UIImage*) uiimage {
196 | UIImage *newImage = [EditViewController effectImage:uiimage byFilterName:@"None"];
197 |
198 | EditViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"theEditView"];
199 |
200 | [viewController setOriginalImage:uiimage];
201 | [viewController setImage:newImage];
202 |
203 | [self presentViewController:viewController animated:YES completion:^{
204 | }];
205 | }
206 |
207 | // 保存图片出现 error
208 | - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error
209 | contextInfo:(void *)contextInfo
210 | {
211 | if (error != NULL)
212 | {
213 | NSLog(@"error - didFinishSavingWithError");
214 |
215 | }
216 | }
217 |
218 | // 获取相机 input
219 | - (AVCaptureDeviceInput *)getVideoInput {
220 |
221 | for (AVCaptureDeviceInput *input in self.session.inputs) {
222 | if ([input.device hasMediaType:AVMediaTypeVideo]) {
223 | return input;
224 | }
225 | }
226 |
227 | return nil;
228 | }
229 |
230 | // 前后摄像头按钮
231 | - (IBAction)clickSwitchCameraButton:(id)sender {
232 |
233 | AVCaptureDeviceInput *currentInput = [self getVideoInput];
234 |
235 | if (currentInput) {
236 | AVCaptureDevicePosition newPosition = AVCaptureDevicePositionFront;
237 | if (currentInput.device.position == AVCaptureDevicePositionFront) {
238 | newPosition = AVCaptureDevicePositionBack;
239 | }
240 |
241 | AVCaptureDevice *newDevice = nil;
242 | NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
243 | for (AVCaptureDevice *device in devices)
244 | {
245 | if ([device position] == newPosition)
246 | {
247 | newDevice = device;
248 | break;
249 | }
250 | }
251 |
252 | NSError *error;
253 | AVCaptureDeviceInput *newInput = [AVCaptureDeviceInput deviceInputWithDevice:newDevice error:&error];
254 |
255 | [self.session beginConfiguration];
256 | [self.session removeInput:currentInput];
257 | [self.session addInput:newInput];
258 | [self.session commitConfiguration];
259 |
260 | // font camera 时隐藏闪光灯按钮
261 | if (newDevice.position == AVCaptureDevicePositionFront) {
262 | [self.flashlightButton setHidden:YES];
263 | } else {
264 | [self.flashlightButton setHidden:NO];
265 | }
266 | }
267 | }
268 |
269 | // 闪光灯按钮
270 | - (IBAction)clickFlashlightButton:(id)sender {
271 | AVCaptureDeviceInput *input = [self getVideoInput];
272 |
273 | [input.device lockForConfiguration:nil];
274 |
275 | if (input.device.flashMode == AVCaptureFlashModeAuto) {
276 | [input.device setFlashMode:AVCaptureFlashModeOff];
277 | } else if (input.device.flashMode == AVCaptureFlashModeOff) {
278 | [input.device setFlashMode:AVCaptureFlashModeOn];
279 | } else {
280 | [input.device setFlashMode:AVCaptureFlashModeAuto];
281 | }
282 |
283 | [input.device unlockForConfiguration];
284 |
285 | NSString *buttonTitle = [self getTitleByFlashlightMode:input.device.flashMode];
286 | [[self flashlightButton] setTitle:buttonTitle forState:normal];
287 |
288 | UIImage *buttonImage = [self getImageByFlashlightMode:input.device.flashMode];
289 | buttonImage = [self imageWithImage:buttonImage scaledToSize:CGRectMake(0,0,40,40).size];
290 | [[self flashlightButton] setImage:buttonImage forState:UIControlStateNormal];
291 |
292 | }
293 |
294 | // 画幅比例按钮
295 | - (IBAction)clickProportionButton:(id)sender {
296 |
297 | hcCameraMode newCameraMode;
298 | if ([self cameraMode] == hcCameraMode3to4) {
299 | newCameraMode = hcCameraMode9to16;
300 | } else {
301 | newCameraMode = [self cameraMode] + 1;
302 | }
303 | [self setCameraMode:newCameraMode];
304 |
305 | [[self proportionButton] setTitle:[self getTitleByCameraMode:[self cameraMode]] forState:UIControlStateNormal];
306 |
307 | AVCaptureVideoPreviewLayer *subPreviewLayer = [[[[self preview] layer] sublayers] objectAtIndex:0];
308 | [subPreviewLayer removeFromSuperlayer];
309 |
310 | CGFloat proportion = [self getPoportionByHcCameraMode:[self cameraMode]];
311 | CGRect rect = [self getFrameByProportion:proportion];
312 | [subPreviewLayer setFrame:rect];
313 | [[[self preview] layer] insertSublayer:subPreviewLayer atIndex:0];
314 | }
315 |
316 | // 初始化按键
317 | - (void) initViewsOfButtons:(AVCaptureFlashMode) flashMode {
318 |
319 | // 闪光灯按钮
320 | NSString *buttonTitle = [self getTitleByFlashlightMode:flashMode];
321 | [[self flashlightButton] setTitle:buttonTitle forState:normal];
322 |
323 | UIImage *buttonImage = [self getImageByFlashlightMode:flashMode];
324 | buttonImage = [self imageWithImage:buttonImage scaledToSize:CGRectMake(0,0,40,40).size];
325 | [[self flashlightButton] setImage:buttonImage forState:UIControlStateNormal];
326 |
327 | // 前后摄像头切换按钮
328 | [[self switchCameraButton] setTitle:@"" forState:UIControlStateNormal];
329 | buttonImage = [UIImage imageNamed:@"switchCamera.png"];
330 | buttonImage = [self imageWithImage:buttonImage scaledToSize:CGRectMake(0,0,40,40).size];
331 | [[self switchCameraButton] setImage:buttonImage forState:UIControlStateNormal];
332 |
333 | // 拍照按钮
334 | [[self snapButton] setTitle:@"" forState:UIControlStateNormal];
335 | buttonImage = [UIImage imageNamed:@"snap.png"];
336 | buttonImage = [self imageWithImage:buttonImage scaledToSize:CGRectMake(0,0,50,50).size];
337 | [[self snapButton] setImage:buttonImage forState:UIControlStateNormal];
338 |
339 | // 画布比例按钮
340 | [[self proportionButton] setTitle:[self getTitleByCameraMode:[self cameraMode]] forState:UIControlStateNormal];
341 | }
342 |
343 | - (NSString *) getTitleByCameraMode:(hcCameraMode) theCameraMode{
344 | NSString *buttonTitle;
345 | if (theCameraMode == hcCameraMode9to16) {
346 | buttonTitle = @"16:9";
347 | } else if (theCameraMode == hcCameraMode1to1) {
348 | buttonTitle = @"1:1";
349 | } else { // hcCameraMode3to4
350 | buttonTitle = @"4:3";
351 | }
352 |
353 | return buttonTitle;
354 | }
355 |
356 |
357 | - (NSString *) getTitleByFlashlightMode:(AVCaptureFlashMode) flashMode {
358 | NSString *buttonTitle;
359 | if (flashMode == AVCaptureFlashModeAuto) {
360 | buttonTitle = @"Auto";
361 | } else if (flashMode == AVCaptureFlashModeOff) {
362 | buttonTitle = @"Off";
363 | } else {
364 | buttonTitle = @"On";
365 | }
366 |
367 | return buttonTitle;
368 | }
369 |
370 | - (UIImage *) getImageByFlashlightMode:(AVCaptureFlashMode) flashMode {
371 |
372 | NSString *imageName;
373 | if (flashMode == AVCaptureFlashModeAuto) {
374 | imageName = @"flashlightAuto.png";
375 | } else if (flashMode == AVCaptureFlashModeOff) {
376 | imageName = @"flashlightOff.png";
377 | } else { // AVCaptureFlashModeOn
378 | imageName = @"flashlightOn.png";
379 | }
380 |
381 | UIImage *buttonImage = [UIImage imageNamed:imageName];
382 |
383 | return buttonImage;
384 | }
385 |
386 | // 根据比例获得缩小后的 size
387 | - (CGSize) sizeWithSize:(CGSize) size poportion:(CGFloat) proportion{
388 |
389 | CGSize screenSize = [[UIScreen mainScreen] bounds].size;
390 | CGFloat screenProportion = screenSize.width / screenSize.height;
391 |
392 | CGSize newSize;
393 | if (proportion > screenProportion) {
394 | newSize.width = size.width;
395 | newSize.height = size.width / proportion;
396 | } else {
397 | newSize.height = size.height;
398 | newSize.width = size.height * proportion;
399 | }
400 |
401 | return newSize;
402 | }
403 |
404 | // 根据 cameraMode 获取比例
405 | - (CGFloat) getPoportionByHcCameraMode:(hcCameraMode) theCameraMode {
406 |
407 | if (theCameraMode == hcCameraMode1to1) {
408 | return 1.0 / 1.0;
409 | } else if (theCameraMode == hcCameraMode3to4) {
410 | return 3.0 / 4.0;
411 | } else {// hcCameraMode9to16
412 | return 9.0 / 16.0;
413 | }
414 | }
415 |
416 | // 根据比例获取 frame
417 | - (CGRect) getFrameByProportion:(CGFloat) proportion {
418 | CGSize screenSize = [[UIScreen mainScreen] bounds].size;
419 |
420 | CGSize newSize = [self sizeWithSize:screenSize poportion:proportion];
421 |
422 | return CGRectMake(screenSize.width / 2 - newSize.width / 2,
423 | screenSize.height / 2 - newSize.height / 2,
424 | newSize.width,
425 | newSize.height);
426 | }
427 |
428 |
429 | @end
430 |
--------------------------------------------------------------------------------
/HanCamera.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 311B7F751A0BBA9F002083C9 /* iTunesArtwork.png in Resources */ = {isa = PBXBuildFile; fileRef = 311B7F741A0BBA9F002083C9 /* iTunesArtwork.png */; };
11 | 3163BFDC1A0DB609008D75B4 /* flashlightAuto.png in Resources */ = {isa = PBXBuildFile; fileRef = 3163BFD91A0DB609008D75B4 /* flashlightAuto.png */; };
12 | 3163BFDD1A0DB609008D75B4 /* flashlightOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 3163BFDA1A0DB609008D75B4 /* flashlightOff.png */; };
13 | 3163BFDE1A0DB609008D75B4 /* flashlightOn.png in Resources */ = {isa = PBXBuildFile; fileRef = 3163BFDB1A0DB609008D75B4 /* flashlightOn.png */; };
14 | 3163BFE01A0DB64A008D75B4 /* snap.png in Resources */ = {isa = PBXBuildFile; fileRef = 3163BFDF1A0DB64A008D75B4 /* snap.png */; };
15 | 3163BFE21A0DE649008D75B4 /* switchCamera.png in Resources */ = {isa = PBXBuildFile; fileRef = 3163BFE11A0DE648008D75B4 /* switchCamera.png */; };
16 | 31BA4F861A11149C008089FC /* EditViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 31BA4F851A11149C008089FC /* EditViewController.m */; };
17 | 31E2ED381A0B1B78008FB715 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 31E2ED371A0B1B78008FB715 /* main.m */; };
18 | 31E2ED3B1A0B1B78008FB715 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 31E2ED3A1A0B1B78008FB715 /* AppDelegate.m */; };
19 | 31E2ED3E1A0B1B78008FB715 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 31E2ED3D1A0B1B78008FB715 /* ViewController.m */; };
20 | 31E2ED411A0B1B78008FB715 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 31E2ED3F1A0B1B78008FB715 /* Main.storyboard */; };
21 | 31E2ED431A0B1B78008FB715 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 31E2ED421A0B1B78008FB715 /* Images.xcassets */; };
22 | 31E2ED461A0B1B78008FB715 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 31E2ED441A0B1B78008FB715 /* LaunchScreen.xib */; };
23 | 31E2ED521A0B1B78008FB715 /* HanCameraTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 31E2ED511A0B1B78008FB715 /* HanCameraTests.m */; };
24 | /* End PBXBuildFile section */
25 |
26 | /* Begin PBXContainerItemProxy section */
27 | 31E2ED4C1A0B1B78008FB715 /* PBXContainerItemProxy */ = {
28 | isa = PBXContainerItemProxy;
29 | containerPortal = 31E2ED2A1A0B1B78008FB715 /* Project object */;
30 | proxyType = 1;
31 | remoteGlobalIDString = 31E2ED311A0B1B78008FB715;
32 | remoteInfo = HanCamera;
33 | };
34 | /* End PBXContainerItemProxy section */
35 |
36 | /* Begin PBXFileReference section */
37 | 311B7F741A0BBA9F002083C9 /* iTunesArtwork.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = iTunesArtwork.png; sourceTree = ""; };
38 | 3163BFD91A0DB609008D75B4 /* flashlightAuto.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flashlightAuto.png; sourceTree = ""; };
39 | 3163BFDA1A0DB609008D75B4 /* flashlightOff.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flashlightOff.png; sourceTree = ""; };
40 | 3163BFDB1A0DB609008D75B4 /* flashlightOn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = flashlightOn.png; sourceTree = ""; };
41 | 3163BFDF1A0DB64A008D75B4 /* snap.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = snap.png; sourceTree = ""; };
42 | 3163BFE11A0DE648008D75B4 /* switchCamera.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = switchCamera.png; sourceTree = ""; };
43 | 31BA4F841A11149C008089FC /* EditViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditViewController.h; sourceTree = ""; };
44 | 31BA4F851A11149C008089FC /* EditViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditViewController.m; sourceTree = ""; };
45 | 31E2ED321A0B1B78008FB715 /* HanCamera.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HanCamera.app; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 31E2ED361A0B1B78008FB715 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
47 | 31E2ED371A0B1B78008FB715 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
48 | 31E2ED391A0B1B78008FB715 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
49 | 31E2ED3A1A0B1B78008FB715 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
50 | 31E2ED3C1A0B1B78008FB715 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
51 | 31E2ED3D1A0B1B78008FB715 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
52 | 31E2ED401A0B1B78008FB715 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
53 | 31E2ED421A0B1B78008FB715 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
54 | 31E2ED451A0B1B78008FB715 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
55 | 31E2ED4B1A0B1B78008FB715 /* HanCameraTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HanCameraTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
56 | 31E2ED501A0B1B78008FB715 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 31E2ED511A0B1B78008FB715 /* HanCameraTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HanCameraTests.m; sourceTree = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | 31E2ED2F1A0B1B78008FB715 /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | );
66 | runOnlyForDeploymentPostprocessing = 0;
67 | };
68 | 31E2ED481A0B1B78008FB715 /* Frameworks */ = {
69 | isa = PBXFrameworksBuildPhase;
70 | buildActionMask = 2147483647;
71 | files = (
72 | );
73 | runOnlyForDeploymentPostprocessing = 0;
74 | };
75 | /* End PBXFrameworksBuildPhase section */
76 |
77 | /* Begin PBXGroup section */
78 | 3163BFD81A0DB5E4008D75B4 /* buttonImage */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 3163BFE11A0DE648008D75B4 /* switchCamera.png */,
82 | 3163BFDF1A0DB64A008D75B4 /* snap.png */,
83 | 3163BFD91A0DB609008D75B4 /* flashlightAuto.png */,
84 | 3163BFDA1A0DB609008D75B4 /* flashlightOff.png */,
85 | 3163BFDB1A0DB609008D75B4 /* flashlightOn.png */,
86 | );
87 | name = buttonImage;
88 | sourceTree = "";
89 | };
90 | 31E2ED291A0B1B78008FB715 = {
91 | isa = PBXGroup;
92 | children = (
93 | 31E2ED341A0B1B78008FB715 /* HanCamera */,
94 | 31E2ED4E1A0B1B78008FB715 /* HanCameraTests */,
95 | 31E2ED331A0B1B78008FB715 /* Products */,
96 | );
97 | sourceTree = "";
98 | };
99 | 31E2ED331A0B1B78008FB715 /* Products */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 31E2ED321A0B1B78008FB715 /* HanCamera.app */,
103 | 31E2ED4B1A0B1B78008FB715 /* HanCameraTests.xctest */,
104 | );
105 | name = Products;
106 | sourceTree = "";
107 | };
108 | 31E2ED341A0B1B78008FB715 /* HanCamera */ = {
109 | isa = PBXGroup;
110 | children = (
111 | 31E2ED391A0B1B78008FB715 /* AppDelegate.h */,
112 | 31E2ED3A1A0B1B78008FB715 /* AppDelegate.m */,
113 | 31E2ED3C1A0B1B78008FB715 /* ViewController.h */,
114 | 31E2ED3D1A0B1B78008FB715 /* ViewController.m */,
115 | 31BA4F841A11149C008089FC /* EditViewController.h */,
116 | 31BA4F851A11149C008089FC /* EditViewController.m */,
117 | 31E2ED3F1A0B1B78008FB715 /* Main.storyboard */,
118 | 31E2ED421A0B1B78008FB715 /* Images.xcassets */,
119 | 31E2ED441A0B1B78008FB715 /* LaunchScreen.xib */,
120 | 31E2ED351A0B1B78008FB715 /* Supporting Files */,
121 | );
122 | path = HanCamera;
123 | sourceTree = "";
124 | };
125 | 31E2ED351A0B1B78008FB715 /* Supporting Files */ = {
126 | isa = PBXGroup;
127 | children = (
128 | 3163BFD81A0DB5E4008D75B4 /* buttonImage */,
129 | 311B7F741A0BBA9F002083C9 /* iTunesArtwork.png */,
130 | 31E2ED361A0B1B78008FB715 /* Info.plist */,
131 | 31E2ED371A0B1B78008FB715 /* main.m */,
132 | );
133 | name = "Supporting Files";
134 | sourceTree = "";
135 | };
136 | 31E2ED4E1A0B1B78008FB715 /* HanCameraTests */ = {
137 | isa = PBXGroup;
138 | children = (
139 | 31E2ED511A0B1B78008FB715 /* HanCameraTests.m */,
140 | 31E2ED4F1A0B1B78008FB715 /* Supporting Files */,
141 | );
142 | path = HanCameraTests;
143 | sourceTree = "";
144 | };
145 | 31E2ED4F1A0B1B78008FB715 /* Supporting Files */ = {
146 | isa = PBXGroup;
147 | children = (
148 | 31E2ED501A0B1B78008FB715 /* Info.plist */,
149 | );
150 | name = "Supporting Files";
151 | sourceTree = "";
152 | };
153 | /* End PBXGroup section */
154 |
155 | /* Begin PBXNativeTarget section */
156 | 31E2ED311A0B1B78008FB715 /* HanCamera */ = {
157 | isa = PBXNativeTarget;
158 | buildConfigurationList = 31E2ED551A0B1B78008FB715 /* Build configuration list for PBXNativeTarget "HanCamera" */;
159 | buildPhases = (
160 | 31E2ED2E1A0B1B78008FB715 /* Sources */,
161 | 31E2ED2F1A0B1B78008FB715 /* Frameworks */,
162 | 31E2ED301A0B1B78008FB715 /* Resources */,
163 | );
164 | buildRules = (
165 | );
166 | dependencies = (
167 | );
168 | name = HanCamera;
169 | productName = HanCamera;
170 | productReference = 31E2ED321A0B1B78008FB715 /* HanCamera.app */;
171 | productType = "com.apple.product-type.application";
172 | };
173 | 31E2ED4A1A0B1B78008FB715 /* HanCameraTests */ = {
174 | isa = PBXNativeTarget;
175 | buildConfigurationList = 31E2ED581A0B1B78008FB715 /* Build configuration list for PBXNativeTarget "HanCameraTests" */;
176 | buildPhases = (
177 | 31E2ED471A0B1B78008FB715 /* Sources */,
178 | 31E2ED481A0B1B78008FB715 /* Frameworks */,
179 | 31E2ED491A0B1B78008FB715 /* Resources */,
180 | );
181 | buildRules = (
182 | );
183 | dependencies = (
184 | 31E2ED4D1A0B1B78008FB715 /* PBXTargetDependency */,
185 | );
186 | name = HanCameraTests;
187 | productName = HanCameraTests;
188 | productReference = 31E2ED4B1A0B1B78008FB715 /* HanCameraTests.xctest */;
189 | productType = "com.apple.product-type.bundle.unit-test";
190 | };
191 | /* End PBXNativeTarget section */
192 |
193 | /* Begin PBXProject section */
194 | 31E2ED2A1A0B1B78008FB715 /* Project object */ = {
195 | isa = PBXProject;
196 | attributes = {
197 | LastUpgradeCheck = 0610;
198 | ORGANIZATIONNAME = "韩畅";
199 | TargetAttributes = {
200 | 31E2ED311A0B1B78008FB715 = {
201 | CreatedOnToolsVersion = 6.1;
202 | };
203 | 31E2ED4A1A0B1B78008FB715 = {
204 | CreatedOnToolsVersion = 6.1;
205 | TestTargetID = 31E2ED311A0B1B78008FB715;
206 | };
207 | };
208 | };
209 | buildConfigurationList = 31E2ED2D1A0B1B78008FB715 /* Build configuration list for PBXProject "HanCamera" */;
210 | compatibilityVersion = "Xcode 3.2";
211 | developmentRegion = English;
212 | hasScannedForEncodings = 0;
213 | knownRegions = (
214 | en,
215 | Base,
216 | );
217 | mainGroup = 31E2ED291A0B1B78008FB715;
218 | productRefGroup = 31E2ED331A0B1B78008FB715 /* Products */;
219 | projectDirPath = "";
220 | projectRoot = "";
221 | targets = (
222 | 31E2ED311A0B1B78008FB715 /* HanCamera */,
223 | 31E2ED4A1A0B1B78008FB715 /* HanCameraTests */,
224 | );
225 | };
226 | /* End PBXProject section */
227 |
228 | /* Begin PBXResourcesBuildPhase section */
229 | 31E2ED301A0B1B78008FB715 /* Resources */ = {
230 | isa = PBXResourcesBuildPhase;
231 | buildActionMask = 2147483647;
232 | files = (
233 | 31E2ED411A0B1B78008FB715 /* Main.storyboard in Resources */,
234 | 3163BFDC1A0DB609008D75B4 /* flashlightAuto.png in Resources */,
235 | 31E2ED461A0B1B78008FB715 /* LaunchScreen.xib in Resources */,
236 | 3163BFDD1A0DB609008D75B4 /* flashlightOff.png in Resources */,
237 | 3163BFE21A0DE649008D75B4 /* switchCamera.png in Resources */,
238 | 311B7F751A0BBA9F002083C9 /* iTunesArtwork.png in Resources */,
239 | 3163BFE01A0DB64A008D75B4 /* snap.png in Resources */,
240 | 31E2ED431A0B1B78008FB715 /* Images.xcassets in Resources */,
241 | 3163BFDE1A0DB609008D75B4 /* flashlightOn.png in Resources */,
242 | );
243 | runOnlyForDeploymentPostprocessing = 0;
244 | };
245 | 31E2ED491A0B1B78008FB715 /* Resources */ = {
246 | isa = PBXResourcesBuildPhase;
247 | buildActionMask = 2147483647;
248 | files = (
249 | );
250 | runOnlyForDeploymentPostprocessing = 0;
251 | };
252 | /* End PBXResourcesBuildPhase section */
253 |
254 | /* Begin PBXSourcesBuildPhase section */
255 | 31E2ED2E1A0B1B78008FB715 /* Sources */ = {
256 | isa = PBXSourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | 31E2ED3E1A0B1B78008FB715 /* ViewController.m in Sources */,
260 | 31E2ED3B1A0B1B78008FB715 /* AppDelegate.m in Sources */,
261 | 31BA4F861A11149C008089FC /* EditViewController.m in Sources */,
262 | 31E2ED381A0B1B78008FB715 /* main.m in Sources */,
263 | );
264 | runOnlyForDeploymentPostprocessing = 0;
265 | };
266 | 31E2ED471A0B1B78008FB715 /* Sources */ = {
267 | isa = PBXSourcesBuildPhase;
268 | buildActionMask = 2147483647;
269 | files = (
270 | 31E2ED521A0B1B78008FB715 /* HanCameraTests.m in Sources */,
271 | );
272 | runOnlyForDeploymentPostprocessing = 0;
273 | };
274 | /* End PBXSourcesBuildPhase section */
275 |
276 | /* Begin PBXTargetDependency section */
277 | 31E2ED4D1A0B1B78008FB715 /* PBXTargetDependency */ = {
278 | isa = PBXTargetDependency;
279 | target = 31E2ED311A0B1B78008FB715 /* HanCamera */;
280 | targetProxy = 31E2ED4C1A0B1B78008FB715 /* PBXContainerItemProxy */;
281 | };
282 | /* End PBXTargetDependency section */
283 |
284 | /* Begin PBXVariantGroup section */
285 | 31E2ED3F1A0B1B78008FB715 /* Main.storyboard */ = {
286 | isa = PBXVariantGroup;
287 | children = (
288 | 31E2ED401A0B1B78008FB715 /* Base */,
289 | );
290 | name = Main.storyboard;
291 | sourceTree = "";
292 | };
293 | 31E2ED441A0B1B78008FB715 /* LaunchScreen.xib */ = {
294 | isa = PBXVariantGroup;
295 | children = (
296 | 31E2ED451A0B1B78008FB715 /* Base */,
297 | );
298 | name = LaunchScreen.xib;
299 | sourceTree = "";
300 | };
301 | /* End PBXVariantGroup section */
302 |
303 | /* Begin XCBuildConfiguration section */
304 | 31E2ED531A0B1B78008FB715 /* Debug */ = {
305 | isa = XCBuildConfiguration;
306 | buildSettings = {
307 | ALWAYS_SEARCH_USER_PATHS = NO;
308 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
309 | CLANG_CXX_LIBRARY = "libc++";
310 | CLANG_ENABLE_MODULES = YES;
311 | CLANG_ENABLE_OBJC_ARC = YES;
312 | CLANG_WARN_BOOL_CONVERSION = YES;
313 | CLANG_WARN_CONSTANT_CONVERSION = YES;
314 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
315 | CLANG_WARN_EMPTY_BODY = YES;
316 | CLANG_WARN_ENUM_CONVERSION = YES;
317 | CLANG_WARN_INT_CONVERSION = YES;
318 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
319 | CLANG_WARN_UNREACHABLE_CODE = YES;
320 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
321 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
322 | COPY_PHASE_STRIP = NO;
323 | ENABLE_STRICT_OBJC_MSGSEND = YES;
324 | GCC_C_LANGUAGE_STANDARD = gnu99;
325 | GCC_DYNAMIC_NO_PIC = NO;
326 | GCC_OPTIMIZATION_LEVEL = 0;
327 | GCC_PREPROCESSOR_DEFINITIONS = (
328 | "DEBUG=1",
329 | "$(inherited)",
330 | );
331 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
332 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
333 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
334 | GCC_WARN_UNDECLARED_SELECTOR = YES;
335 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
336 | GCC_WARN_UNUSED_FUNCTION = YES;
337 | GCC_WARN_UNUSED_VARIABLE = YES;
338 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
339 | MTL_ENABLE_DEBUG_INFO = YES;
340 | ONLY_ACTIVE_ARCH = YES;
341 | SDKROOT = iphoneos;
342 | };
343 | name = Debug;
344 | };
345 | 31E2ED541A0B1B78008FB715 /* Release */ = {
346 | isa = XCBuildConfiguration;
347 | buildSettings = {
348 | ALWAYS_SEARCH_USER_PATHS = NO;
349 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
350 | CLANG_CXX_LIBRARY = "libc++";
351 | CLANG_ENABLE_MODULES = YES;
352 | CLANG_ENABLE_OBJC_ARC = YES;
353 | CLANG_WARN_BOOL_CONVERSION = YES;
354 | CLANG_WARN_CONSTANT_CONVERSION = YES;
355 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
356 | CLANG_WARN_EMPTY_BODY = YES;
357 | CLANG_WARN_ENUM_CONVERSION = YES;
358 | CLANG_WARN_INT_CONVERSION = YES;
359 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
360 | CLANG_WARN_UNREACHABLE_CODE = YES;
361 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
362 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
363 | COPY_PHASE_STRIP = YES;
364 | ENABLE_NS_ASSERTIONS = NO;
365 | ENABLE_STRICT_OBJC_MSGSEND = YES;
366 | GCC_C_LANGUAGE_STANDARD = gnu99;
367 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
368 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
369 | GCC_WARN_UNDECLARED_SELECTOR = YES;
370 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
371 | GCC_WARN_UNUSED_FUNCTION = YES;
372 | GCC_WARN_UNUSED_VARIABLE = YES;
373 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
374 | MTL_ENABLE_DEBUG_INFO = NO;
375 | SDKROOT = iphoneos;
376 | VALIDATE_PRODUCT = YES;
377 | };
378 | name = Release;
379 | };
380 | 31E2ED561A0B1B78008FB715 /* Debug */ = {
381 | isa = XCBuildConfiguration;
382 | buildSettings = {
383 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
384 | INFOPLIST_FILE = HanCamera/Info.plist;
385 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
386 | PRODUCT_NAME = "$(TARGET_NAME)";
387 | };
388 | name = Debug;
389 | };
390 | 31E2ED571A0B1B78008FB715 /* Release */ = {
391 | isa = XCBuildConfiguration;
392 | buildSettings = {
393 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
394 | INFOPLIST_FILE = HanCamera/Info.plist;
395 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
396 | PRODUCT_NAME = "$(TARGET_NAME)";
397 | };
398 | name = Release;
399 | };
400 | 31E2ED591A0B1B78008FB715 /* Debug */ = {
401 | isa = XCBuildConfiguration;
402 | buildSettings = {
403 | BUNDLE_LOADER = "$(TEST_HOST)";
404 | FRAMEWORK_SEARCH_PATHS = (
405 | "$(SDKROOT)/Developer/Library/Frameworks",
406 | "$(inherited)",
407 | );
408 | GCC_PREPROCESSOR_DEFINITIONS = (
409 | "DEBUG=1",
410 | "$(inherited)",
411 | );
412 | INFOPLIST_FILE = HanCameraTests/Info.plist;
413 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
414 | PRODUCT_NAME = "$(TARGET_NAME)";
415 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HanCamera.app/HanCamera";
416 | };
417 | name = Debug;
418 | };
419 | 31E2ED5A1A0B1B78008FB715 /* Release */ = {
420 | isa = XCBuildConfiguration;
421 | buildSettings = {
422 | BUNDLE_LOADER = "$(TEST_HOST)";
423 | FRAMEWORK_SEARCH_PATHS = (
424 | "$(SDKROOT)/Developer/Library/Frameworks",
425 | "$(inherited)",
426 | );
427 | INFOPLIST_FILE = HanCameraTests/Info.plist;
428 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
429 | PRODUCT_NAME = "$(TARGET_NAME)";
430 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HanCamera.app/HanCamera";
431 | };
432 | name = Release;
433 | };
434 | /* End XCBuildConfiguration section */
435 |
436 | /* Begin XCConfigurationList section */
437 | 31E2ED2D1A0B1B78008FB715 /* Build configuration list for PBXProject "HanCamera" */ = {
438 | isa = XCConfigurationList;
439 | buildConfigurations = (
440 | 31E2ED531A0B1B78008FB715 /* Debug */,
441 | 31E2ED541A0B1B78008FB715 /* Release */,
442 | );
443 | defaultConfigurationIsVisible = 0;
444 | defaultConfigurationName = Release;
445 | };
446 | 31E2ED551A0B1B78008FB715 /* Build configuration list for PBXNativeTarget "HanCamera" */ = {
447 | isa = XCConfigurationList;
448 | buildConfigurations = (
449 | 31E2ED561A0B1B78008FB715 /* Debug */,
450 | 31E2ED571A0B1B78008FB715 /* Release */,
451 | );
452 | defaultConfigurationIsVisible = 0;
453 | defaultConfigurationName = Release;
454 | };
455 | 31E2ED581A0B1B78008FB715 /* Build configuration list for PBXNativeTarget "HanCameraTests" */ = {
456 | isa = XCConfigurationList;
457 | buildConfigurations = (
458 | 31E2ED591A0B1B78008FB715 /* Debug */,
459 | 31E2ED5A1A0B1B78008FB715 /* Release */,
460 | );
461 | defaultConfigurationIsVisible = 0;
462 | defaultConfigurationName = Release;
463 | };
464 | /* End XCConfigurationList section */
465 | };
466 | rootObject = 31E2ED2A1A0B1B78008FB715 /* Project object */;
467 | }
468 |
--------------------------------------------------------------------------------