调整ios端代码为custom项目代码 避免疯狂调用导致的webview崩溃

This commit is contained in:
zher52 2020-05-12 12:10:19 +08:00
parent ba4f77468f
commit 0a2c778c5f
23 changed files with 1550 additions and 3 deletions

View File

@ -84,8 +84,8 @@
</platform>
<!-- ios -->
<platform name="ios">
<!-- old plugin's ios -->
<!-- <platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Camera">
<param name="ios-package" value="CDVCamera" />
@ -112,8 +112,68 @@
<framework src="CoreGraphics.framework" />
<framework src="AVFoundation.framework" />
</platform>
</platform> -->
<!-- ios -->
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Camera">
<param name="ios-package" value="CustomCamera" />
</feature>
</config-file>
<config-file target="config.xml" parent="/*">
<feature name="LocalStorage">
<param name="ios-package" value="CDVLocalStorage" />
</feature>
</config-file>
<header-file src="src/ios/classes/CustomCamera.h" />
<source-file src="src/ios/classes/CustomCamera.m" />
<header-file src="src/ios/classes/AVCamPreviewView.h" />
<source-file src="src/ios/classes/AVCamPreviewView.m" />
<header-file src="src/ios/classes/AVCamViewController.h" />
<source-file src="src/ios/classes/AVCamViewController.m" />
<header-file src="src/ios/classes/CameraParameter.h" />
<source-file src="src/ios/classes/CameraParameter.m" />
<resource-file src="src/ios/classes/AVCamViewController_iPhone.xib" />
<resource-file src="src/ios/classes/AVCamViewController_iPad.xib" />
<resource-file src="src/ios/image/icon_back.png" />
<resource-file src="src/ios/image/icon_capture_pressed.png" />
<resource-file src="src/ios/image/icon_capture.png" />
<resource-file src="src/ios/image/icon_delete.png" />
<resource-file src="src/ios/image/icon_flash_auto.png" />
<resource-file src="src/ios/image/icon_flash_off.png" />
<resource-file src="src/ios/image/icon_flash.png" />
<resource-file src="src/ios/image/icon_flip.png" />
<resource-file src="src/ios/image/icon_max.png" />
<resource-file src="src/ios/image/icon_min.png" />
<resource-file src="src/ios/image/icon_submit.png" />
<resource-file src="src/ios/image/sample.png" />
<framework src="CoreGraphics.framework" weak="true" />
<framework src="AssetsLibrary.framework" weak="true" />
<framework src="AVFoundation.framework" weak="true" />
<framework src="CoreAudio.framework" weak="true" />
<framework src="CoreLocation.framework" weak="true" />
<framework src="MobileCoreServices.framework" weak="true" />
<preference name="CAMERA_USAGE_DESCRIPTION" default="This app requires access to your camera to take pictures" />
<config-file target="*-Info.plist" parent="NSCameraUsageDescription">
<string>$CAMERA_USAGE_DESCRIPTION</string>
</config-file>
<preference name="MICROPHONE_USAGE_DESCRIPTION" default="This app requires access to your microphone to take pictures" />
<config-file target="*-Info.plist" parent="NSMicrophoneUsageDescription">
<string>$MICROPHONE_USAGE_DESCRIPTION</string>
</config-file>
<preference name="PHOTO_LIBRARY_ADD_USAGE_DESCRIPTION" default="This app requires access to your photo library to save your pictures" />
<config-file target="*-Info.plist" parent="NSPhotoLibraryAddUsageDescription">
<string>$PHOTO_LIBRARY_ADD_USAGE_DESCRIPTION</string>
</config-file>
</platform>
<!-- browser -->
<platform name="browser">
<config-file target="config.xml" parent="/*">

View File

@ -0,0 +1,9 @@
#import <UIKit/UIKit.h>
@class AVCaptureSession;
@interface AVCamPreviewView : UIView
@property (nonatomic) AVCaptureSession *session;
@end

View File

@ -0,0 +1,21 @@
#import "AVCamPreviewView.h"
#import <AVFoundation/AVFoundation.h>
@implementation AVCamPreviewView
+ (Class)layerClass
{
return [AVCaptureVideoPreviewLayer class];
}
- (AVCaptureSession *)session
{
return [(AVCaptureVideoPreviewLayer *)[self layer] session];
}
- (void)setSession:(AVCaptureSession *)session
{
[(AVCaptureVideoPreviewLayer *)[self layer] setSession:session];
}
@end

View File

@ -0,0 +1,35 @@
#import <UIKit/UIKit.h>
#import "CameraParameter.h"
@interface AVCamViewController : UIViewController
{
NSData *_imageData;
void (^_callback)(UIImage *, NSString *, NSString *);
UIPinchGestureRecognizer *twoFingerPinch;
CGRect frameBtnThumb;
UIImage *capturedImage;
NSData *capturedImageData;
BOOL isRotated;
CGFloat fDist;
}
@property (weak, nonatomic) IBOutlet UIView *saveBgPanel;
@property (weak, nonatomic) IBOutlet UIView *topBgPanel;
@property (weak, nonatomic) IBOutlet UIImageView *capturedImageView;
@property (weak, nonatomic) IBOutlet UIButton *btnBigDeletePicture;
@property (weak, nonatomic) IBOutlet UIButton *btnDeletePicture;
@property (weak, nonatomic) IBOutlet UIButton *btnSaveImage;
@property (weak, nonatomic) IBOutlet UIButton *btnBigSaveImage;
@property (weak, nonatomic) IBOutlet UISlider *opacitySlider;
@property (nonatomic, retain) CameraParameter *params;
- (id)initWithParams:(CameraParameter *)parameter WithCallback:(void (^)(UIImage *, NSString *, NSString *))callback;
@end

View File

@ -0,0 +1,811 @@
#import "AVCamViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "AVCamPreviewView.h"
static void *CapturingStillImageContext = &CapturingStillImageContext;
static void *RecordingContext = &RecordingContext;
static void *SessionRunningAndDeviceAuthorizedContext = &SessionRunningAndDeviceAuthorizedContext;
@interface AVCamViewController () <AVCaptureFileOutputRecordingDelegate>
// For use in the storyboards.
@property (nonatomic, weak) IBOutlet AVCamPreviewView *previewView;
@property (nonatomic, weak) IBOutlet UIButton *recordButton;
@property (nonatomic, weak) IBOutlet UIButton *cameraButton;
@property (nonatomic, weak) IBOutlet UIButton *stillButton;
@property (weak, nonatomic) IBOutlet UIButton *btnThumb;
@property (weak, nonatomic) IBOutlet UIButton *btnFlash;
@property (weak, nonatomic) IBOutlet UIButton *btnBack;
@property (nonatomic, weak) IBOutlet UIImageView *imgSmallThumbNail;
@property (nonatomic, weak) IBOutlet UIImageView *imgBigThumbNail;
- (IBAction)onTapThumb:(id)sender;
- (IBAction)onTapCameraFlash:(id)sender;
- (IBAction)onBack:(id)sender;
- (IBAction)toggleMovieRecording:(id)sender;
- (IBAction)changeCamera:(id)sender;
- (IBAction)snapStillImage:(id)sender;
- (IBAction)focusAndExposeTap:(UIGestureRecognizer *)gestureRecognizer;
// Session management.
@property (nonatomic) dispatch_queue_t sessionQueue; // Communicate with the session and other session objects on this queue.
@property (nonatomic) AVCaptureSession *session;
@property (nonatomic) AVCaptureDeviceInput *videoDeviceInput;
@property (nonatomic) AVCaptureMovieFileOutput *movieFileOutput;
@property (nonatomic) AVCaptureStillImageOutput *stillImageOutput;
// Utilities.
@property (nonatomic) UIBackgroundTaskIdentifier backgroundRecordingID;
@property (nonatomic, getter = isDeviceAuthorized) BOOL deviceAuthorized;
@property (nonatomic, readonly, getter = isSessionRunningAndDeviceAuthorized) BOOL sessionRunningAndDeviceAuthorized;
@property (nonatomic) BOOL lockInterfaceRotation;
@property (nonatomic) id runtimeErrorHandlingObserver;
@end
@implementation AVCamViewController
@synthesize params;
- (BOOL)isSessionRunningAndDeviceAuthorized {
return [[self session] isRunning] && [self isDeviceAuthorized];
}
+ (NSSet *)keyPathsForValuesAffectingSessionRunningAndDeviceAuthorized {
return [NSSet setWithObjects:@"session.running", @"deviceAuthorized", nil];
}
- (id)initWithParams:(CameraParameter *)parameter WithCallback:(void (^)(UIImage *, NSString *, NSString *))callback {
self = [super initWithNibName:nil bundle:nil];
self.params = parameter;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self = [super initWithNibName:@"AVCamViewController_iPad" bundle:nil];
}
else {
self = [super initWithNibName:@"AVCamViewController_iPhone" bundle:nil];
}
if (self) {
_callback = callback;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Create the AVCaptureSession
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[self setSession:session];
// Setup the preview view
[[self previewView] setSession:session];
// Check for device authorization
[self checkDeviceAuthorizationStatus];
// In general it is not safe to mutate an AVCaptureSession or any of its inputs, outputs, or connections from multiple threads at the same time.
// Why not do all of this on the main queue?
// -[AVCaptureSession startRunning] is a blocking call which can take a long time. We dispatch session setup to the sessionQueue so that the main queue isn't blocked (which keeps the UI responsive).
dispatch_queue_t sessionQueue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL);
[self setSessionQueue:sessionQueue];
dispatch_async(sessionQueue, ^{
[self setBackgroundRecordingID:UIBackgroundTaskInvalid];
NSError *error = nil;
AVCaptureDevice *videoDevice;
if (params.nDefaultCamera == 0) {
videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionBack];
}
else {
videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:AVCaptureDevicePositionFront];
}
AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
if (![videoDevice hasTorch]) {
self.btnFlash.hidden = YES;
// self.cameraButton.center = self.btnThumb.center;
// self.btnThumb.center = self.btnFlash.center;
}
});
if (error) {
NSLog(@"%@", error);
}
if ([session canAddInput:videoDeviceInput]) {
[session addInput:videoDeviceInput];
[self setVideoDeviceInput:videoDeviceInput];
dispatch_async(dispatch_get_main_queue(), ^{
// Why are we dispatching this to the main queue?
// Because AVCaptureVideoPreviewLayer is the backing layer for AVCamPreviewView and UIView can only be manipulated on main thread.
// Note: As an exception to the above rule, it is not necessary to serialize video orientation changes on the AVCaptureVideoPreviewLayers connection with other session manipulation.
[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)[[UIApplication sharedApplication] statusBarOrientation]];
});
}
AVCaptureDevice *audioDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
AVCaptureDeviceInput *audioDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error];
if (error) {
NSLog(@"%@", error);
}
if ([session canAddInput:audioDeviceInput]) {
[session addInput:audioDeviceInput];
}
AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
if ([session canAddOutput:movieFileOutput]) {
[session addOutput:movieFileOutput];
AVCaptureConnection *connection = [movieFileOutput connectionWithMediaType:AVMediaTypeVideo];
if ([connection isVideoStabilizationSupported])
//connection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeAuto;
//[connection setEnablesVideoStabilizationWhenAvailable:YES];
[self setMovieFileOutput:movieFileOutput];
}
AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
if ([session canAddOutput:stillImageOutput]) {
[stillImageOutput setOutputSettings:@{ AVVideoCodecKey : AVVideoCodecJPEG }];
[session addOutput:stillImageOutput];
[self setStillImageOutput:stillImageOutput];
}
});
[self initialize];
}
- (void)viewWillAppear:(BOOL)animated {
dispatch_async([self sessionQueue], ^{
[self addObserver:self forKeyPath:@"sessionRunningAndDeviceAuthorized" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:SessionRunningAndDeviceAuthorizedContext];
[self addObserver:self forKeyPath:@"stillImageOutput.capturingStillImage" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:CapturingStillImageContext];
[self addObserver:self forKeyPath:@"movieFileOutput.recording" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:RecordingContext];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[self videoDeviceInput] device]];
__weak AVCamViewController *weakSelf = self;
[self setRuntimeErrorHandlingObserver:[[NSNotificationCenter defaultCenter] addObserverForName:AVCaptureSessionRuntimeErrorNotification object:[self session] queue:nil usingBlock: ^(NSNotification *note) {
AVCamViewController *strongSelf = weakSelf;
dispatch_async([strongSelf sessionQueue], ^{
// Manually restarting the session since it must have been stopped due to an error.
[[strongSelf session] startRunning];
[[strongSelf recordButton] setTitle:NSLocalizedString(@"Record", @"Recording button record title") forState:UIControlStateNormal];
});
}]];
[[self session] startRunning];
});
}
- (void)viewDidDisappear:(BOOL)animated {
dispatch_async([self sessionQueue], ^{
[[self session] stopRunning];
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[self videoDeviceInput] device]];
[[NSNotificationCenter defaultCenter] removeObserver:[self runtimeErrorHandlingObserver]];
[self removeObserver:self forKeyPath:@"sessionRunningAndDeviceAuthorized" context:SessionRunningAndDeviceAuthorizedContext];
[self removeObserver:self forKeyPath:@"stillImageOutput.capturingStillImage" context:CapturingStillImageContext];
[self removeObserver:self forKeyPath:@"movieFileOutput.recording" context:RecordingContext];
});
}
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (BOOL)shouldAutorotate {
// Disable autorotation of the interface when recording is in progress.
return ![self lockInterfaceRotation];
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
// return UIInterfaceOrientationMaskPortrait;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] setVideoOrientation:(AVCaptureVideoOrientation)toInterfaceOrientation];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == CapturingStillImageContext) {
BOOL isCapturingStillImage = [change[NSKeyValueChangeNewKey] boolValue];
if (isCapturingStillImage) {
[self runStillImageCaptureAnimation];
}
}
else if (context == RecordingContext) {
BOOL isRecording = [change[NSKeyValueChangeNewKey] boolValue];
dispatch_async(dispatch_get_main_queue(), ^{
if (isRecording) {
[[self cameraButton] setEnabled:NO];
[[self recordButton] setTitle:NSLocalizedString(@"Stop", @"Recording button stop title") forState:UIControlStateNormal];
[[self recordButton] setEnabled:YES];
}
else {
[[self cameraButton] setEnabled:YES];
[[self recordButton] setTitle:NSLocalizedString(@"Record", @"Recording button record title") forState:UIControlStateNormal];
[[self recordButton] setEnabled:YES];
}
});
}
else if (context == SessionRunningAndDeviceAuthorizedContext) {
BOOL isRunning = [change[NSKeyValueChangeNewKey] boolValue];
dispatch_async(dispatch_get_main_queue(), ^{
if (isRunning) {
[[self cameraButton] setEnabled:YES];
[[self recordButton] setEnabled:YES];
[[self stillButton] setEnabled:YES];
}
else {
[[self cameraButton] setEnabled:NO];
[[self recordButton] setEnabled:NO];
[[self stillButton] setEnabled:NO];
}
});
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
#pragma mark Actions
- (IBAction)toggleMovieRecording:(id)sender {
[[self recordButton] setEnabled:NO];
dispatch_async([self sessionQueue], ^{
if (![[self movieFileOutput] isRecording]) {
[self setLockInterfaceRotation:YES];
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
// Setup background task. This is needed because the captureOutput:didFinishRecordingToOutputFileAtURL: callback is not received until AVCam returns to the foreground unless you request background execution time. This also ensures that there will be time to write the file to the assets library when AVCam is backgrounded. To conclude this background execution, -endBackgroundTask is called in -recorder:recordingDidFinishToOutputFileURL:error: after the recorded file has been saved.
[self setBackgroundRecordingID:[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]];
}
// Update the orientation on the movie file output video connection before starting recording.
[[[self movieFileOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];
// Turning OFF flash for video recording
[AVCamViewController setFlashMode:AVCaptureFlashModeOff forDevice:[[self videoDeviceInput] device]];
// Start recording to a temporary file.
NSString *outputFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"movie" stringByAppendingPathExtension:@"mov"]];
[[self movieFileOutput] startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputFilePath] recordingDelegate:self];
}
else {
[[self movieFileOutput] stopRecording];
}
});
}
- (IBAction)changeCamera:(id)sender {
[[self cameraButton] setEnabled:NO];
[[self recordButton] setEnabled:NO];
[[self stillButton] setEnabled:NO];
dispatch_async([self sessionQueue], ^{
AVCaptureDevice *currentVideoDevice = [[self videoDeviceInput] device];
AVCaptureDevicePosition preferredPosition = AVCaptureDevicePositionUnspecified;
AVCaptureDevicePosition currentPosition = [currentVideoDevice position];
switch (currentPosition) {
case AVCaptureDevicePositionUnspecified:
preferredPosition = AVCaptureDevicePositionBack;
break;
case AVCaptureDevicePositionBack:
preferredPosition = AVCaptureDevicePositionFront;
break;
case AVCaptureDevicePositionFront:
preferredPosition = AVCaptureDevicePositionBack;
break;
}
AVCaptureDevice *videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:preferredPosition];
AVCaptureDeviceInput *videoDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
self.btnFlash.tag = 0;
if ([videoDevice hasTorch] && [videoDevice hasFlash]) {
[videoDevice lockForConfiguration:nil];
[videoDevice setTorchMode:NO];
[videoDevice setFlashMode:AVCaptureFlashModeOn];
[videoDevice unlockForConfiguration];
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
self.btnFlash.tag = 0;
self.btnFlash.hidden = NO;
return;
}
if (![videoDevice hasTorch]) {
self.btnFlash.hidden = YES;
}
else if ([videoDevice hasTorch] && params.bSwitchFlash) {
self.btnFlash.hidden = NO;
}
});
[[self session] beginConfiguration];
[[self session] removeInput:[self videoDeviceInput]];
if ([[self session] canAddInput:videoDeviceInput]) {
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:currentVideoDevice];
[AVCamViewController setFlashMode:AVCaptureFlashModeAuto forDevice:videoDevice];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:videoDevice];
[[self session] addInput:videoDeviceInput];
[self setVideoDeviceInput:videoDeviceInput];
}
else {
[[self session] addInput:[self videoDeviceInput]];
}
[[self session] commitConfiguration];
dispatch_async(dispatch_get_main_queue(), ^{
[[self cameraButton] setEnabled:YES];
[[self recordButton] setEnabled:YES];
[[self stillButton] setEnabled:YES];
});
});
}
- (IBAction)snapStillImage:(id)sender {
dispatch_async([self sessionQueue], ^{
// Update the orientation on the still image output video connection before capturing.
[[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:[[(AVCaptureVideoPreviewLayer *)[[self previewView] layer] connection] videoOrientation]];
// Flash set to Auto for Still Capture
[AVCamViewController setFlashMode:AVCaptureFlashModeAuto forDevice:[[self videoDeviceInput] device]];
// Capture a still image.
[[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:[[self stillImageOutput] connectionWithMediaType:AVMediaTypeVideo] completionHandler: ^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
if (imageDataSampleBuffer) {
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
capturedImage = [[UIImage alloc] initWithData:imageData];
capturedImageData = imageData;
[self takePicture];
}
}];
});
}
- (IBAction)focusAndExposeTap:(UIGestureRecognizer *)gestureRecognizer {
CGPoint devicePoint = [(AVCaptureVideoPreviewLayer *)[[self previewView] layer] captureDevicePointOfInterestForPoint:[gestureRecognizer locationInView:[gestureRecognizer view]]];
[self focusWithMode:AVCaptureFocusModeAutoFocus exposeWithMode:AVCaptureExposureModeAutoExpose atDevicePoint:devicePoint monitorSubjectAreaChange:YES];
}
- (void)subjectAreaDidChange:(NSNotification *)notification {
CGPoint devicePoint = CGPointMake(.5, .5);
[self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposeWithMode:AVCaptureExposureModeContinuousAutoExposure atDevicePoint:devicePoint monitorSubjectAreaChange:NO];
}
#pragma mark File Output Delegate
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error {
if (error)
NSLog(@"%@", error);
[self setLockInterfaceRotation:NO];
// Note the backgroundRecordingID for use in the ALAssetsLibrary completion handler to end the background task associated with this recording. This allows a new recording to be started, associated with a new UIBackgroundTaskIdentifier, once the movie file output's -isRecording is back to NO which happens sometime after this method returns.
UIBackgroundTaskIdentifier backgroundRecordingID = [self backgroundRecordingID];
[self setBackgroundRecordingID:UIBackgroundTaskInvalid];
[[[ALAssetsLibrary alloc] init] writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock: ^(NSURL *assetURL, NSError *error) {
if (error)
NSLog(@"%@", error);
[[NSFileManager defaultManager] removeItemAtURL:outputFileURL error:nil];
if (backgroundRecordingID != UIBackgroundTaskInvalid)
[[UIApplication sharedApplication] endBackgroundTask:backgroundRecordingID];
}];
}
#pragma mark Device Configuration
- (void)focusWithMode:(AVCaptureFocusMode)focusMode exposeWithMode:(AVCaptureExposureMode)exposureMode atDevicePoint:(CGPoint)point monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange {
dispatch_async([self sessionQueue], ^{
AVCaptureDevice *device = [[self videoDeviceInput] device];
NSError *error = nil;
if ([device lockForConfiguration:&error]) {
if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:focusMode]) {
[device setFocusMode:focusMode];
[device setFocusPointOfInterest:point];
}
if ([device isExposurePointOfInterestSupported] && [device isExposureModeSupported:exposureMode]) {
[device setExposureMode:exposureMode];
[device setExposurePointOfInterest:point];
}
[device setSubjectAreaChangeMonitoringEnabled:monitorSubjectAreaChange];
[device unlockForConfiguration];
}
else {
NSLog(@"%@", error);
}
});
}
+ (void)setFlashMode:(AVCaptureFlashMode)flashMode forDevice:(AVCaptureDevice *)device {
if ([device hasFlash] && [device isFlashModeSupported:flashMode]) {
NSError *error = nil;
if ([device lockForConfiguration:&error]) {
[device setFlashMode:flashMode];
[device unlockForConfiguration];
}
else {
NSLog(@"%@", error);
}
}
}
+ (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPosition:(AVCaptureDevicePosition)position {
NSArray *devices = [AVCaptureDevice devicesWithMediaType:mediaType];
AVCaptureDevice *captureDevice = [devices firstObject];
for (AVCaptureDevice *device in devices) {
if ([device position] == position) {
captureDevice = device;
break;
}
}
return captureDevice;
}
#pragma mark UI
- (void)runStillImageCaptureAnimation {
dispatch_async(dispatch_get_main_queue(), ^{
[[[self previewView] layer] setOpacity:0.0];
[UIView animateWithDuration:.25 animations: ^{
[[[self previewView] layer] setOpacity:1.0];
}];
});
}
- (void)checkDeviceAuthorizationStatus {
NSString *mediaType = AVMediaTypeVideo;
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler: ^(BOOL granted) {
if (granted) {
//Granted access to mediaType
[self setDeviceAuthorized:YES];
}
else {
//Not granted access to mediaType
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:@"AVCam!"
message:@"AVCam doesn't have permission to use Camera, please change privacy settings"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
[self setDeviceAuthorized:NO];
});
}
}];
}
- (IBAction)onTapThumb:(id)sender {
UIButton *btnThumb = (UIButton *)sender;
self.imgSmallThumbNail.hidden = btnThumb.selected;
self.imgBigThumbNail.hidden = !btnThumb.selected;
btnThumb.selected = !btnThumb.selected;
}
- (IBAction)onTapCameraFlash:(id)sender {
UIButton *btnCameraFlash = (UIButton *)sender;
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (btnCameraFlash.tag == 0) {
[btnCameraFlash setImage:[UIImage imageNamed:@"icon_flash.png"] forState:UIControlStateNormal];
btnCameraFlash.tag = 1;
if ([device hasTorch] && [device hasFlash]) {
[device lockForConfiguration:nil];
[device setTorchMode:!device.torchActive];
[device setFlashMode:AVCaptureFlashModeOn];
[device unlockForConfiguration];
}
return;
}
else if (btnCameraFlash.tag == 1) {
[btnCameraFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
btnCameraFlash.tag = 0;
if ([device hasTorch] && [device hasFlash]) {
[device lockForConfiguration:nil];
[device setTorchMode:!device.torchActive];
[device setFlashMode:AVCaptureFlashModeOff];
[device unlockForConfiguration];
}
return;
}
}
- (IBAction)onBack:(id)sender {
_callback(nil, @"3", @"Camera closed before takin a picture.");
}
- (void)addPinchGesture {
twoFingerPinch = [[UIPinchGestureRecognizer alloc]
initWithTarget:self
action:@selector(twoFingerPinch:)];
[self.view addGestureRecognizer:twoFingerPinch];
}
- (void)addOpacitySlider {
CGAffineTransform trans = CGAffineTransformMakeRotation(M_PI_2 * (-1));
self.opacitySlider.transform = trans;
[self.opacitySlider addTarget:self action:@selector(onChangeOpacitySlider) forControlEvents:UIControlEventValueChanged];
self.opacitySlider.value = 1;
}
- (void)initialize {
fDist = self.btnThumb.center.x - self.cameraButton.center.x;
capturedImage = [[UIImage alloc] init];
capturedImageData = [[NSData alloc] init];
[self addOpacitySlider];
[self addPinchGesture];
self.capturedImageView.hidden = YES;
self.saveBgPanel.hidden = YES;
self.btnBigDeletePicture.hidden = self.btnDeletePicture.hidden = YES;
self.btnBigSaveImage.hidden = self.btnSaveImage.hidden = YES;
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
NSInteger max = (screenSize.width > screenSize.height) ? screenSize.width : screenSize.height;
UIImage *newImage = [self imageWithImage:[UIImage imageWithData:self.params.bgImageData] scaledToMaxWidth:max maxHeight:max];
self.imgBigThumbNail.image = newImage;
self.imgSmallThumbNail.image = [UIImage imageWithData:self.params.bgImageData];
self.btnThumb.hidden = !params.bMiniature;
self.btnFlash.hidden = !params.bSwitchFlash;
self.cameraButton.hidden = !params.bSwitchCamera;
self.opacitySlider.hidden = !params.bOpacity;
if (!params.bgImageData) {
self.imgBigThumbNail.hidden = YES;
self.imgSmallThumbNail.hidden = YES;
}
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (params.nDefaultFlash == 1) {
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash.png"] forState:UIControlStateNormal];
self.btnFlash.tag = 1;
if ([device hasTorch] && [device hasFlash]) {
[device lockForConfiguration:nil];
[device setTorchMode:YES];
[device setFlashMode:AVCaptureFlashModeOn];
[device unlockForConfiguration];
}
}
else {
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
self.btnFlash.tag = 0;
if ([device hasTorch] && [device hasFlash]) {
[device lockForConfiguration:nil];
[device setTorchMode:NO];
[device setFlashMode:AVCaptureFlashModeOn];
[device unlockForConfiguration];
}
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if (params.bgImageData1) {
isRotated = !isRotated;
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
NSInteger max = (screenSize.width > screenSize.height) ? screenSize.width : screenSize.height;
if (isRotated) {
UIImage *newImage = [self imageWithImage:[UIImage imageWithData:self.params.bgImageData1] scaledToMaxWidth:max maxHeight:max];
self.imgBigThumbNail.image = newImage;
self.imgSmallThumbNail.image = [UIImage imageWithData:params.bgImageData1];
}
else {
UIImage *newImage = [self imageWithImage:[UIImage imageWithData:self.params.bgImageData] scaledToMaxWidth:max maxHeight:max];
self.imgBigThumbNail.image = newImage;
self.imgSmallThumbNail.image = [UIImage imageWithData:params.bgImageData];
}
}
}
- (void)takePicture {
[self setLockInterfaceRotation:YES];
self.capturedImageView.image = capturedImage;
self.capturedImageView.hidden = NO;
self.saveBgPanel.hidden = NO;
self.btnBigDeletePicture.hidden = self.btnDeletePicture.hidden = NO;
self.btnBigSaveImage.hidden = self.btnSaveImage.hidden = NO;
self.stillButton.hidden = self.btnFlash.hidden = self.cameraButton.hidden = YES;
frameBtnThumb = self.btnThumb.frame;
self.btnThumb.frame = self.btnFlash.frame;
self.imgSmallThumbNail.frame = CGRectOffset(self.imgSmallThumbNail.frame, 0, -self.saveBgPanel.frame.size.height);
}
- (IBAction)onDeletePicture:(id)sender {
[self setLockInterfaceRotation:NO];
capturedImage = nil;
self.capturedImageView.image = nil;
self.capturedImageView.hidden = YES;
self.btnBigDeletePicture.hidden = self.btnDeletePicture.hidden = YES;
self.btnBigSaveImage.hidden = self.btnSaveImage.hidden = YES;
self.saveBgPanel.hidden = YES;
self.btnThumb.frame = frameBtnThumb;
self.stillButton.hidden = self.btnFlash.hidden = NO;
//control camera button
self.cameraButton.hidden = !params.bSwitchCamera;
[self.cameraButton setEnabled:params.bSwitchCamera];
//control flash button
if (params.bSwitchFlash) {
AVCaptureDevice *currentVideoDevice = [[self videoDeviceInput] device];
AVCaptureDevicePosition currentPosition = [currentVideoDevice position];
AVCaptureDevice *videoDevice = [AVCamViewController deviceWithMediaType:AVMediaTypeVideo preferringPosition:currentPosition];
switch (currentPosition) {
case AVCaptureDevicePositionUnspecified:
case AVCaptureDevicePositionBack:
{
if (self.btnFlash.tag == 0) {
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash_auto.png"] forState:UIControlStateNormal];
if ([videoDevice hasTorch] && [videoDevice hasFlash]) {
[videoDevice lockForConfiguration:nil];
[videoDevice setTorchMode:videoDevice.torchActive];
[videoDevice setFlashMode:AVCaptureFlashModeOff];
[videoDevice unlockForConfiguration];
}
}
else if (self.btnFlash.tag == 1) {
[self.btnFlash setImage:[UIImage imageNamed:@"icon_flash.png"] forState:UIControlStateNormal];
if ([videoDevice hasTorch] && [videoDevice hasFlash]) {
[videoDevice lockForConfiguration:nil];
[videoDevice setTorchMode:videoDevice.torchActive];
[videoDevice setFlashMode:AVCaptureFlashModeOn];
[videoDevice unlockForConfiguration];
}
}
break;
}
case AVCaptureDevicePositionFront:
break;
}
if (![videoDevice hasTorch] || ![videoDevice hasFlash]) {
self.btnFlash.hidden = YES;
}
else {
self.btnFlash.hidden = !params.bSwitchFlash;
[self.btnFlash setEnabled:params.bSwitchFlash];
}
}
else {
self.btnFlash.hidden = YES;
}
self.imgSmallThumbNail.frame = CGRectOffset(self.imgSmallThumbNail.frame, 0, self.saveBgPanel.frame.size.height);
}
- (IBAction)onSaveImage:(id)sender {
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicator.center = self.view.center;
[self.view addSubview:activityIndicator];
[activityIndicator startAnimating];
if (params.bSaveInGallery) {
[[[ALAssetsLibrary alloc] init] writeImageToSavedPhotosAlbum:[capturedImage CGImage] orientation:(ALAssetOrientation)[capturedImage imageOrientation] completionBlock:nil];
}
[self.view setUserInteractionEnabled:NO];
_callback([UIImage imageWithData:capturedImageData], nil, nil);
}
- (void)onChangeOpacitySlider {
self.imgSmallThumbNail.alpha = self.opacitySlider.value;
self.imgBigThumbNail.alpha = self.opacitySlider.value;
}
- (void)twoFingerPinch:(UIPinchGestureRecognizer *)recognizer {
if (self.lockInterfaceRotation) {
return;
}
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
CGFloat fMaxZoomFactor = device.activeFormat.videoMaxZoomFactor;
if (fMaxZoomFactor > 5)
fMaxZoomFactor = 5;
CGFloat fNewScale = recognizer.scale * device.videoZoomFactor;
if (fNewScale > 1.0f && fNewScale < fMaxZoomFactor) {
[device lockForConfiguration:nil];
[device rampToVideoZoomFactor:fNewScale withRate:3];
[device unlockForConfiguration];
}
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
return orientation == UIDeviceOrientationPortrait;
}
#pragma mark -Scale image
- (UIImage *)imageWithImage:(UIImage *)image scaledToMaxWidth:(CGFloat)width maxHeight:(CGFloat)height {
CGFloat oldWidth = image.size.width;
CGFloat oldHeight = image.size.height;
CGFloat scaleFactor = (oldWidth > oldHeight) ? width / oldWidth : height / oldHeight;
CGFloat newHeight = oldHeight * scaleFactor;
CGFloat newWidth = oldWidth * scaleFactor;
CGSize newSize = CGSizeMake(newWidth, newHeight);
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(newSize, NO, [[UIScreen mainScreen] scale]);
}
else {
UIGraphicsBeginImageContext(newSize);
}
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end

View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="6254" systemVersion="14A389" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AVCamViewController">
<connections>
<outlet property="btnBigDeletePicture" destination="IqJ-oc-995" id="T1H-10-ESB"/>
<outlet property="btnBigSaveImage" destination="EFe-fE-P8a" id="P0Z-Xm-thh"/>
<outlet property="btnDeletePicture" destination="S1N-v6-cZw" id="1TW-yQ-2Ul"/>
<outlet property="btnFlash" destination="KMs-9J-eHV" id="pdI-VZ-buj"/>
<outlet property="btnSaveImage" destination="JJc-KF-LjK" id="att-go-Xq7"/>
<outlet property="btnThumb" destination="NW3-H0-02v" id="9az-rc-6zl"/>
<outlet property="cameraButton" destination="br3-lo-te3" id="9er-L2-Q49"/>
<outlet property="capturedImageView" destination="aNd-OH-3PR" id="FB6-Dl-sSA"/>
<outlet property="imgBigThumbNail" destination="hb3-4z-EqI" id="bXK-S1-JY5"/>
<outlet property="imgSmallThumbNail" destination="7Tf-kP-S1C" id="yk1-9p-mnP"/>
<outlet property="opacitySlider" destination="D3e-gE-Un5" id="Vl5-37-0Gj"/>
<outlet property="previewView" destination="vHe-RW-WQc" id="WqV-SM-Xgc"/>
<outlet property="saveBgPanel" destination="xaA-dP-8ce" id="FGL-y1-FJb"/>
<outlet property="stillButton" destination="cxS-Qn-d9p" id="Joi-8C-0gM"/>
<outlet property="topBgPanel" destination="kso-6k-eTa" id="sZi-gu-mzH"/>
<outlet property="view" destination="iN0-l3-epB" id="88I-Oa-O0G"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" id="vHe-RW-WQc" customClass="AVCamPreviewView">
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="aNd-OH-3PR">
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="hb3-4z-EqI">
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="cxS-Qn-d9p">
<rect key="frame" x="344" y="941" width="80" height="76"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<state key="normal" image="icon_capture.png"/>
<state key="selected" image="icon_capture_pressed.png"/>
<state key="highlighted" image="icon_capture_pressed.png"/>
<connections>
<action selector="snapStillImage:" destination="-1" eventType="touchUpInside" id="LsD-dw-Fw0"/>
</connections>
</button>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="7Tf-kP-S1C">
<rect key="frame" x="20" y="934" width="90" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</imageView>
<view alpha="0.5" contentMode="scaleToFill" id="xaA-dP-8ce">
<rect key="frame" x="0.0" y="934" width="768" height="90"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="IqJ-oc-995">
<rect key="frame" x="0.0" y="0.0" width="376" height="90"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<state key="normal">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="XkX-0N-K4g"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="EFe-fE-P8a">
<rect key="frame" x="384" y="0.0" width="384" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
<state key="normal">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="pMu-f6-poC"/>
</connections>
</button>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="S1N-v6-cZw">
<rect key="frame" x="147" y="20" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<state key="normal" image="icon_delete.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="7ty-gh-NHC"/>
</connections>
</button>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="JJc-KF-LjK">
<rect key="frame" x="566" y="20" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<state key="normal" image="icon_submit.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="mry-0F-fqI"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
<view alpha="0.5" contentMode="scaleToFill" id="kso-6k-eTa">
<rect key="frame" x="0.0" y="0.0" width="768" height="90"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="7Wz-zM-ysY">
<rect key="frame" x="20" y="20" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_back.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onBack:" destination="-1" eventType="touchUpInside" id="zpX-8h-Pcs"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="br3-lo-te3">
<rect key="frame" x="480" y="20" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_flip.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="changeCamera:" destination="-1" eventType="touchUpInside" id="2JV-vM-qU3"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="NW3-H0-02v">
<rect key="frame" x="597" y="25" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_min.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="selected" image="icon_max.png"/>
<connections>
<action selector="onTapThumb:" destination="-1" eventType="touchUpInside" id="kJr-cv-LaQ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="KMs-9J-eHV">
<rect key="frame" x="690" y="20" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_flash_auto.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onTapCameraFlash:" destination="-1" eventType="touchUpInside" id="hq4-uE-TO5"/>
</connections>
</button>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="D3e-gE-Un5">
<rect key="frame" x="479" y="497" width="512" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</slider>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</objects>
<resources>
<image name="icon_back.png" width="60" height="60"/>
<image name="icon_capture.png" width="128" height="128"/>
<image name="icon_capture_pressed.png" width="128" height="128"/>
<image name="icon_delete.png" width="60" height="60"/>
<image name="icon_flash_auto.png" width="60" height="60"/>
<image name="icon_flip.png" width="60" height="60"/>
<image name="icon_max.png" width="60" height="60"/>
<image name="icon_min.png" width="60" height="60"/>
<image name="icon_submit.png" width="60" height="60"/>
<image name="sample.png" width="483" height="263"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination"/>
</simulatedMetricsContainer>
</document>

View File

@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14A389" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AVCamViewController">
<connections>
<outlet property="btnBack" destination="JSx-s3-uHS" id="gtj-U7-7eS"/>
<outlet property="btnBigDeletePicture" destination="9ml-dK-r4P" id="v1z-D4-2aN"/>
<outlet property="btnBigSaveImage" destination="P2D-hm-Kcg" id="81p-6x-fIz"/>
<outlet property="btnDeletePicture" destination="J6B-b3-9jL" id="Odf-du-kBy"/>
<outlet property="btnFlash" destination="BRk-mk-jo0" id="JMg-ha-GzP"/>
<outlet property="btnSaveImage" destination="gCj-9O-Lhz" id="Tg2-gh-nlr"/>
<outlet property="btnThumb" destination="OWo-yv-W9g" id="0S3-x9-HAa"/>
<outlet property="cameraButton" destination="jnK-sC-Roz" id="yhA-LL-bdK"/>
<outlet property="capturedImageView" destination="mfI-LM-QPE" id="aXs-aV-ggH"/>
<outlet property="imgBigThumbNail" destination="GAn-hK-ROm" id="dc7-tm-wNM"/>
<outlet property="imgSmallThumbNail" destination="MJV-kJ-EX5" id="HgP-9H-c4t"/>
<outlet property="opacitySlider" destination="gf9-Ju-OcL" id="jn8-NJ-iVO"/>
<outlet property="previewView" destination="wgh-5M-pgU" id="03T-sp-Ynl"/>
<outlet property="saveBgPanel" destination="AJN-IB-tiU" id="epU-gC-TWb"/>
<outlet property="stillButton" destination="usa-GD-lMO" id="hXu-yT-Tuj"/>
<outlet property="topBgPanel" destination="qKn-KP-yGM" id="bL1-dO-Na2"/>
<outlet property="view" destination="iN0-l3-epB" id="98Z-ee-Lmg"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" id="wgh-5M-pgU" customClass="AVCamPreviewView">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="mfI-LM-QPE">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="GAn-hK-ROm">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</imageView>
<button opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="usa-GD-lMO">
<rect key="frame" x="135" y="513" width="50" height="50"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<state key="normal" image="icon_capture.png"/>
<state key="selected" image="icon_capture_pressed.png"/>
<state key="highlighted" image="icon_capture_pressed.png"/>
<connections>
<action selector="snapStillImage:" destination="-1" eventType="touchUpInside" id="l6I-0I-IBm"/>
</connections>
</button>
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sample.png" id="MJV-kJ-EX5">
<rect key="frame" x="10" y="508" width="60" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</imageView>
<view alpha="0.5" contentMode="scaleToFill" id="AJN-IB-tiU">
<rect key="frame" x="0.0" y="508" width="320" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="9ml-dK-r4P">
<rect key="frame" x="0.0" y="0.0" width="160" height="60"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxX="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<state key="normal">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="MyT-W6-Zcm"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" id="P2D-hm-Kcg">
<rect key="frame" x="160" y="0.0" width="160" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<state key="normal">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="HXF-We-dau"/>
</connections>
</button>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="gCj-9O-Lhz">
<rect key="frame" x="245" y="15" width="30" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
<state key="normal" image="icon_submit.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onSaveImage:" destination="-1" eventType="touchUpInside" id="hLE-rb-Fpv"/>
</connections>
</button>
<button opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="J6B-b3-9jL">
<rect key="frame" x="45" y="15" width="30" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<state key="normal" image="icon_delete.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onDeletePicture:" destination="-1" eventType="touchUpInside" id="vby-qq-Okp"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
<view alpha="0.5" contentMode="scaleToFill" id="qKn-KP-yGM">
<rect key="frame" x="0.0" y="0.0" width="320" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="OWo-yv-W9g">
<rect key="frame" x="234" y="17" width="25" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_min.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<state key="selected" image="icon_max.png"/>
<connections>
<action selector="onTapThumb:" destination="-1" eventType="touchUpInside" id="zSf-cq-fIV"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="jnK-sC-Roz">
<rect key="frame" x="180" y="15" width="30" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_flip.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="changeCamera:" destination="-1" eventType="touchUpInside" id="UhB-S7-CvX"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="JSx-s3-uHS">
<rect key="frame" x="10" y="15" width="30" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_back.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onBack:" destination="-1" eventType="touchUpInside" id="dpX-Bq-HAw"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="BRk-mk-jo0">
<rect key="frame" x="280" y="15" width="30" height="30"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<state key="normal" image="icon_flash_auto.png">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<action selector="onTapCameraFlash:" destination="-1" eventType="touchUpInside" id="mKZ-w5-NhW"/>
</connections>
</button>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="0.5" minValue="0.0" maxValue="1" id="gf9-Ju-OcL">
<rect key="frame" x="199" y="269" width="200" height="31"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
</slider>
</subviews>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
<gestureRecognizers/>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<nil key="simulatedStatusBarMetrics"/>
</view>
</objects>
<resources>
<image name="icon_back.png" width="60" height="60"/>
<image name="icon_capture.png" width="128" height="128"/>
<image name="icon_capture_pressed.png" width="128" height="128"/>
<image name="icon_delete.png" width="60" height="60"/>
<image name="icon_flash_auto.png" width="60" height="60"/>
<image name="icon_flip.png" width="60" height="60"/>
<image name="icon_max.png" width="60" height="60"/>
<image name="icon_min.png" width="60" height="60"/>
<image name="icon_submit.png" width="60" height="60"/>
<image name="sample.png" width="483" height="263"/>
</resources>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>
<simulatedScreenMetrics key="destination" type="retina4"/>
</simulatedMetricsContainer>
</document>

View File

@ -0,0 +1,29 @@
#import <Foundation/Foundation.h>
#import <Cordova/CDV.h>
@interface CameraParameter : NSObject
{
}
@property(nonatomic, retain) NSData *bgImageData;
@property(nonatomic, retain) NSData *bgImageData1;
@property(nonatomic, assign) BOOL bMiniature;
@property(nonatomic, assign) BOOL bSaveInGallery;
@property(nonatomic, assign) int nCameraFlashMode;
@property(nonatomic, retain) NSString* strCameraBGColor;
@property(nonatomic, retain) NSString* strCameraPressedBG;
@property(nonatomic, assign) CGFloat fQuality;
@property(nonatomic, assign) BOOL bOpacity;
@property(nonatomic, assign) int nDefaultFlash;
@property(nonatomic, assign) BOOL bSwitchFlash;
@property(nonatomic, assign) int nDefaultCamera;
@property(nonatomic, assign) BOOL bSwitchCamera;
-(id) initWithCommand :(CDVInvokedUrlCommand *)command;
@end

View File

@ -0,0 +1,58 @@
#import "CameraParameter.h"
@implementation CameraParameter
{
}
@synthesize bgImageData;
@synthesize bgImageData1;
@synthesize bMiniature;
@synthesize bSaveInGallery;
@synthesize nCameraFlashMode;
@synthesize strCameraBGColor;
@synthesize strCameraPressedBG;
@synthesize fQuality;
@synthesize bOpacity;
@synthesize nDefaultFlash;
@synthesize bSwitchFlash;
@synthesize nDefaultCamera;
@synthesize bSwitchCamera;
- (id)initWithCommand:(CDVInvokedUrlCommand *)command {
// [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
// mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];
if (self = [super init]) {
// NSString *strData = [command argumentAtIndex:0];
// if (strData) {
// bgImageData = [[NSData alloc] initWithBase64EncodedString:strData options:0];
// }
// else {
bgImageData = nil;
// }
// NSString *strData1 = [command argumentAtIndex:1];
// if (strData1) {
// bgImageData1 = [[NSData alloc] initWithBase64EncodedString:strData1 options:0];
// }
// else {
bgImageData1 = nil;
// }
bMiniature = false; //[[command argumentAtIndex:2] boolValue];
bSaveInGallery = [[command argumentAtIndex:9] boolValue];
strCameraBGColor = @"#e26760"; //[command argumentAtIndex:4];
strCameraPressedBG = @"#dc453d"; //[command argumentAtIndex:5];
fQuality = [[command argumentAtIndex:0] intValue];
bOpacity = true; //[[command argumentAtIndex:7] boolValue];
nDefaultFlash = 2; //[[command argumentAtIndex:8] intValue];
bSwitchFlash = true; //[[command argumentAtIndex:9] boolValue];
nDefaultCamera = 0; //[[command argumentAtIndex:10] intValue];
bSwitchCamera = true; //[[command argumentAtIndex:11] boolValue];
}
return self;
}
@end

32
src/ios/classes/CustomCamera.h Executable file
View File

@ -0,0 +1,32 @@
#import <Cordova/CDV.h>
@interface CustomCamera : CDVPlugin<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
{
CDVInvokedUrlCommand *lastCommand;
int nSourceType;
int nDestType;
NSData *bgImageData;
NSData *bgImageData1;
BOOL miniature;
BOOL saveInGallery;
int nCameraFlashMode;
NSString* clrCameraBG;
NSString* clrCameraPressedBG;
CGFloat quality;
BOOL opacity;
int defaultFlash;
BOOL switchFlash;
int defaultCamera;
BOOL switchCamera;
NSString *filename;
}
- (void)startCamera:(CDVInvokedUrlCommand*)command;
- (void)takePicture:(CDVInvokedUrlCommand*)command;
@end

124
src/ios/classes/CustomCamera.m Executable file
View File

@ -0,0 +1,124 @@
#import "CustomCamera.h"
#import "AVCamViewController.h"
#import "CameraParameter.h"
@implementation CustomCamera
- (void)takePicture:(CDVInvokedUrlCommand *)command {
[self startCamera: command];
}
- (void)startCamera:(CDVInvokedUrlCommand *)command {
lastCommand = command;
NSString *guid = [[NSUUID new] UUIDString];
NSString *uniqueFileName = [NSString stringWithFormat:@"%@.jpg", guid];
filename = uniqueFileName;
nSourceType = 1;
nDestType = 0;
CameraParameter *param = [[CameraParameter alloc] initWithCommand:lastCommand];
if (nSourceType == 0) {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePickerController.delegate = self;
[self.viewController presentViewController:imagePickerController animated:YES completion:nil];
}
else {
if (![UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]) {
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"No rear camera detected"];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
else if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Camera is not accessible"];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
else {
AVCamViewController *cameraViewController = [[AVCamViewController alloc] initWithParams:param WithCallback: ^(UIImage *image, NSString *errorCode, NSString *message) {
@autoreleasepool {
if (image) {
if (nDestType == 0) {
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
NSString *strEncodeData = [imageData base64EncodedStringWithOptions:0];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsString:strEncodeData];
[self.viewController dismissViewControllerAnimated:YES completion:nil];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
else {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:filename];
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
[imageData writeToFile:imagePath atomically:YES];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsString:[[NSURL fileURLWithPath:imagePath] absoluteString]];
[self.viewController dismissViewControllerAnimated:YES completion:nil];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
}
else {
//error
NSDictionary *error = @{ @"code":errorCode, @"message":message };
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:error];
[self.viewController dismissViewControllerAnimated:YES completion:nil];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
}
}];
[self.viewController presentViewController:cameraViewController animated:YES completion:nil];
}
}
}
// This method is called when an image has been chosen from the library or taken from the camera.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
//You can retrieve the actual UIImage
UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];
//Or you can get the image url from AssetsLibrary
// NSURL *path = [info valueForKey:UIImagePickerControllerReferenceURL];
[picker dismissViewControllerAnimated:YES completion: ^{
@autoreleasepool {
if (nDestType == 0) {
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
NSString *strEncodeData = [imageData base64EncodedStringWithOptions:0];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsString:strEncodeData];
[self.commandDelegate sendPluginResult:result callbackId:lastCommand.callbackId];
}
else {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:filename];
NSData *imageData = UIImageJPEGRepresentation(image, quality / 100);
//[self deleteFileWithName:imagePath];
[imageData writeToFile:imagePath atomically:YES];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsString:[[NSURL fileURLWithPath:imagePath] absoluteString]];
[self.commandDelegate sendPluginResult:result callbackId:lastCommand.callbackId];
}
}
}];
}
- (void)deleteFileWithName:(NSString *)fileName {
NSFileManager *manager = [NSFileManager defaultManager];
// Need to check if the to be deleted file exists.
if ([manager fileExistsAtPath:fileName]) {
NSError *error = nil;
// This function also returnsYES if the item was removed successfully or if path was nil.
// Returns NO if an error occurred.
[manager removeItemAtPath:fileName error:&error];
if (error) {
NSLog(@"There is an Error: %@", error);
}
}
else {
NSLog(@"File %@ doesn't exists", fileName);
}
}
@end

BIN
src/ios/image/icon_back.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/ios/image/icon_delete.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
src/ios/image/icon_flash.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
src/ios/image/icon_flash_auto.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
src/ios/image/icon_flash_off.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
src/ios/image/icon_flip.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
src/ios/image/icon_max.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/ios/image/icon_min.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/ios/image/icon_submit.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
src/ios/image/sample.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB