[英]save image with QRCode in document directory in background thread
我正在开发一个应用程序,在该应用程序中,我从iOS画廊中选取了10张图像,然后生成所有图像的QRCode,然后使用后台线程将所有内容保存在文档目录中,但是问题是当我更改选项卡栏时要说在处理开始时我移到另一个标签栏视图,然后后台线程停止,我只得到3或4个存储的图像。 我使用了不同的不同背景函数来实现这一点,就像我使用了NSOperationQueue一样,我也创建了单独的类,然后尝试保存但未成功。 我使用的代码:
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info
{
NSLog(@"%@",info);
[self dismissViewControllerAnimated:YES completion:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[self saveallD:info];
dispatch_async(dispatch_get_main_queue(), ^{
});
});
}
-(void)saveallD:(NSArray*)info
{
// int i=0;
for (NSDictionary *dict in info)
{
if ([dict objectForKey:UIImagePickerControllerMediaType] == ALAssetTypePhoto)
{
// i++;
if ([dict objectForKey:UIImagePickerControllerOriginalImage])
{
UIImage* chosenImage=[dict objectForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImagePNGRepresentation(chosenImage);
CGFloat scale= (100*1024)/(CGFloat)[imageData length]; // For 100KB.
UIImage *small_image=[UIImage imageWithCGImage:chosenImage.CGImage scale:scale orientation:chosenImage.imageOrientation];
NSData *imagefinaldata = UIImageJPEGRepresentation(small_image, scale*1.00);
//UIImage *imgCompressed = [self compressImage:chosenImage];
//NSData *imagefinaldata = UIImagePNGRepresentation(imgCompressed);
BOOL qrcodedetected = NO;
[[NSUserDefaults standardUserDefaults] setObject:imagefinaldata forKey:@"imagesaved"];
// QRCode detector
NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:detectorOptions];
NSArray *features = [faceDetector featuresInImage:chosenImage.CIImage];
CIQRCodeFeature *faceFeature;
for(faceFeature in features)
{
qrcodedetected = YES;
self.decodedstr = [NSString stringWithFormat:@"%@",faceFeature.messageString];
break;
}
if (!qrcodedetected)
{
int timestamp = [[NSDate date] timeIntervalSince1970];
NSString*selectedFolder=[[NSUserDefaults standardUserDefaults] valueForKey:@"SelectedFolder"];
if ([selectedFolder isEqualToString:@""] || [selectedFolder isKindOfClass:[NSNull class]] || selectedFolder.length==0 )
{
selectedFolder=@"Default";
}
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 2), ^{
// time-consuming task
NSLog(@"basepath..%@",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]);
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",selectedFolder]];
//NSString *QRstringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:@"QRimages"];
if ([[NSFileManager defaultManager] fileExistsAtPath:stringPath])
{
// [imagefinaldata writeToFile:savedImagePath atomically:NO];
// stringPath = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *stringPath2 = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *savedImagePath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",timestamp]];
[self writeImageToFile:stringPath2 :savedImagePath :imagefinaldata];
NSString *savedAudioPath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.m4a",timestamp]];
//NSData*recordedAudioData=[NSData dataWithContentsOfURL:_recorder.url];
if ([autoRecordingCheck isEqualToString:@"ON"])
{
[self writeAudioToFile:stringPath2 :savedAudioPath];
}
}
else
{
[[NSFileManager defaultManager]createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:nil];
NSString *stringPath2 = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *savedImagePath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",timestamp]];
[self writeImageToFile:stringPath2 :savedImagePath :imagefinaldata];
NSString *savedAudioPath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.m4a",timestamp]];
//NSData*recordedAudioData=[NSData dataWithContentsOfURL:_recorder.url];
if ([autoRecordingCheck isEqualToString:@"ON"])
{
[self writeAudioToFile:stringPath2 :savedAudioPath];
}
// [imagefinaldata writeToFile:savedImagePath atomically:NO];
}
NSString *savedImagePath = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",timestamp]];
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
NSData *data = [savedImagePath dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKey:@"inputMessage"];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage
fromRect:[outputImage extent]];
UIImage *image = [UIImage imageWithCGImage:cgImage
scale:1.0
orientation:UIImageOrientationUp];
// Resize without interpolating
UIImage *resized = [self resizeImage:image
withQuality:kCGInterpolationNone
rate:5.0];
NSData* QRdata = UIImagePNGRepresentation(resized);
NSString *stringPath2 = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *savedImagePath2 = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"QR%d.png",timestamp]];
[self writeQRToFile:stringPath2 :savedImagePath2 :QRdata];
// [self performSegueWithIdentifier:@"addfilters" sender:nil];
// dispatch_async(dispatch_get_main_queue(), ^{
// [SVProgressHUD dismiss];
// });
//
// });
}
else
{
[self galleryalert];
}
}
}
else
{
NSLog(@"UIImagePickerControllerReferenceURL = %@", dict);
}
}
如果有人有任何类型的解决方案,请告诉我。 将不胜感激。 提前致谢!
这是我正在谈论的代码。 根据您的需要进行更改。
BackgroundOperation.h
@protocol BackgroundOperationDelegate <NSObject>
-(void)operationCompleted;
-(void)operationInterrupted;
@end
@interface BackgroundOperation : NSObject
@property (nonatomic, weak) id<BackgroundOperationDelegate> delegate;
+(BackgroundOperation*)sharedInstance;
-(void)saveallD:(NSArray*)info;
@end
BackgroundOperation.m
#import "BackgroundOperation.h"
@implementation BackgroundOperation
static BackgroundOperation *_sharedInstance = nil;
+(BackgroundOperation*)sharedInstance{
if(_sharedInstance == nil){
_sharedInstance = [[BackgroundOperation alloc] init];
}
return _sharedInstance;
}
- (id)init {
if(self = [super init]) {
}
return self;
}
-(void)saveallD:(NSArray*)infoArray
{
int i=0;
NSArray *info = [NSArray arrayWithArray:infoArray];
for (NSDictionary *dict in info)
{
if ([dict objectForKey:UIImagePickerControllerMediaType] == ALAssetTypePhoto)
{
i++;
if ([dict objectForKey:UIImagePickerControllerOriginalImage])
{
UIImage* chosenImage=[dict objectForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImagePNGRepresentation(chosenImage);
CGFloat scale= (100*1024)/(CGFloat)[imageData length]; // For 100KB.
UIImage *small_image=[UIImage imageWithCGImage:chosenImage.CGImage scale:scale orientation:chosenImage.imageOrientation];
NSData *imagefinaldata = UIImageJPEGRepresentation(small_image, scale*1.00);
//UIImage *imgCompressed = [self compressImage:chosenImage];
//NSData *imagefinaldata = UIImagePNGRepresentation(imgCompressed);
BOOL qrcodedetected = NO;
[[NSUserDefaults standardUserDefaults] setObject:imagefinaldata forKey:@"imagesaved"];
// QRCode detector
NSDictionary *detectorOptions = @{ CIDetectorAccuracy : CIDetectorAccuracyHigh };
CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:detectorOptions];
NSArray *features = [faceDetector featuresInImage:chosenImage.CIImage];
CIQRCodeFeature *faceFeature;
for(faceFeature in features)
{
qrcodedetected = YES;
self.decodedstr = [NSString stringWithFormat:@"%@",faceFeature.messageString];
break;
}
if (!qrcodedetected)
{
int timestamp = [[NSDate date] timeIntervalSince1970];
NSString*selectedFolder=[[NSUserDefaults standardUserDefaults] valueForKey:@"SelectedFolder"];
if ([selectedFolder isEqualToString:@""] || [selectedFolder isKindOfClass:[NSNull class]] || selectedFolder.length==0 )
{
selectedFolder=@"Default";
}
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 2), ^{
// time-consuming task
NSLog(@"basepath..%@",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]);
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:[NSString stringWithFormat:@"%@",selectedFolder]];
//NSString *QRstringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:@"QRimages"];
if ([[NSFileManager defaultManager] fileExistsAtPath:stringPath])
{
// [imagefinaldata writeToFile:savedImagePath atomically:NO];
// stringPath = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *stringPath2 = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *savedImagePath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",timestamp]];
[self writeImageToFile:stringPath2 :savedImagePath :imagefinaldata];
NSString *savedAudioPath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.m4a",timestamp]];
//NSData*recordedAudioData=[NSData dataWithContentsOfURL:_recorder.url];
if ([autoRecordingCheck isEqualToString:@"ON"])
{
[self writeAudioToFile:stringPath2 :savedAudioPath];
}
}
else
{
[[NSFileManager defaultManager]createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:nil];
NSString *stringPath2 = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *savedImagePath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",timestamp]];
[self writeImageToFile:stringPath2 :savedImagePath :imagefinaldata];
NSString *savedAudioPath = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.m4a",timestamp]];
//NSData*recordedAudioData=[NSData dataWithContentsOfURL:_recorder.url];
if ([autoRecordingCheck isEqualToString:@"ON"])
{
[self writeAudioToFile:stringPath2 :savedAudioPath];
}
// [imagefinaldata writeToFile:savedImagePath atomically:NO];
}
NSString *savedImagePath = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.png",timestamp]];
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
[filter setDefaults];
NSData *data = [savedImagePath dataUsingEncoding:NSUTF8StringEncoding];
[filter setValue:data forKey:@"inputMessage"];
CIImage *outputImage = [filter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:outputImage
fromRect:[outputImage extent]];
UIImage *image = [UIImage imageWithCGImage:cgImage
scale:1.0
orientation:UIImageOrientationUp];
// Resize without interpolating
UIImage *resized = [self resizeImage:image
withQuality:kCGInterpolationNone
rate:5.0];
NSData* QRdata = UIImagePNGRepresentation(resized);
NSString *stringPath2 = [stringPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",timestamp]];
NSString *savedImagePath2 = [stringPath2 stringByAppendingPathComponent:[NSString stringWithFormat:@"QR%d.png",timestamp]];
[self writeQRToFile:stringPath2 :savedImagePath2 :QRdata];
// [self performSegueWithIdentifier:@"addfilters" sender:nil];
// dispatch_async(dispatch_get_main_queue(), ^{
// [SVProgressHUD dismiss];
// });
//
// });
}
else
{
[self galleryalert];
}
}
}
else
{
NSLog(@"UIImagePickerControllerReferenceURL = %@", dict);
}
}
if(i+1==info.count)
{
[self.delegate operationCompleted];
}
else
{
[self.delegate operationInterrupted];
}
}
@end
您可以在视图控制器中像下面这样拨打电话
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info
{
NSLog(@"%@",info);
[self dismissViewControllerAnimated:YES completion:nil];
[[BackgroundOperation sharedInstance] setDelegate:self];
[[BackgroundOperation sharedInstance] saveallD:info];
}
确保在任务完成后重写视图控制器中的BackgroundOperationDelegate方法以获取回调
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.