Ios 使用CIGaussianBlur和CIAffineClamp保存相位集
首先,我问了我的上司,甚至是办公室里的老板,但他们没有回答我的问题如何在同时应用两个过滤器的情况下保存相位集? 我有一个使用PHAssets编辑资产元数据(照片/视频)的项目。现在,我可以通过应用标记和过滤器来修改图像。请参见此示例: 我最近遇到了一个关于CIGaussianBlur生成的额外边界的问题,我了解到我必须使用CIAffineClamp过滤器来修复该问题: 不幸的是,当我需要应用两个过滤器时,我不知道如何保存相集或修改相集。下面是我应用两个过滤器的代码:Ios 使用CIGaussianBlur和CIAffineClamp保存相位集,ios,objective-c,cifilter,phasset,Ios,Objective C,Cifilter,Phasset,首先,我问了我的上司,甚至是办公室里的老板,但他们没有回答我的问题如何在同时应用两个过滤器的情况下保存相位集? 我有一个使用PHAssets编辑资产元数据(照片/视频)的项目。现在,我可以通过应用标记和过滤器来修改图像。请参见此示例: 我最近遇到了一个关于CIGaussianBlur生成的额外边界的问题,我了解到我必须使用CIAffineClamp过滤器来修复该问题: 不幸的是,当我需要应用两个过滤器时,我不知道如何保存相集或修改相集。下面是我应用两个过滤器的代码: // G: If B
// G: If Blur, then adjust first the frame before applying blur!
if ([filterName isEqualToString:@"CIGaussianBlur"])
{
[filter setValue:inputImageForFilter forKey:@"inputImage"];
CGFloat blurLevel = 20.0f;
[filter setValue:[NSNumber numberWithFloat:blurLevel] forKey:@"inputRadius"];
CIImage* filterInputImage = [CIImage imageWithCGImage:originalImage.CGImage];
CIFilter* filter = [CIFilter filterWithName:filterName];
CIFilter *clampFilter = [CIFilter filterWithName:@"CIAffineClamp"];
[clampFilter setDefaults];
[clampFilter setValue:filterInputImage forKey:kCIInputImageKey];
[filter setValue:clampFilter.outputImage forKey:kCIInputImageKey];
[filter setValue:@10.0f forKey:@"inputRadius"];
CIImage* filterOutputImage = [filter valueForKey:kCIOutputImageKey];
CGImageRef createdImage = [context createCGImage:filterOutputImage fromRect:[filterInputImage extent]];
UIImage* outputImage = [UIImage imageWithCGImage:createdImage];
dispatch_async(dispatch_get_main_queue(), ^{
strongSelf.capturedImageView.image = outputImage;
strongSelf.capturedImageView.contentMode = UIViewContentModeScaleAspectFit;
[strongSelf.capturedImageView layoutSubviews];
});
strongSelf.appliedFilter.filterName = filterName;
strongSelf.appliedFilter.editingInput = contentEditingInput;
strongSelf.appliedFilter.outputImage = filterOutputImage;
CGImageRelease(createdImage);
createdImage = nil;
}
下面是我保存数据的代码:
- (void)doneButtonAction:(id)sender
{
// G: Handle Nil FilterName for Fixing Crash :)
if (self.appliedFilter.filterName == nil) {
// G: just pop to the view controller next to root, which is the Camera View Controller in Photo Mode.
[self.navigationController popToViewController:self.navigationController.viewControllers[1] animated:YES];
}
else{
// Create a PHAdjustmentData object that describes the filter that was applied.
PHAdjustmentData *adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:AdjustmentFormatIdentifier formatVersion:@"1.0" data:[self.appliedFilter.filterName dataUsingEncoding:NSUTF8StringEncoding]];
PHAdjustmentData *affineClamp = [[PHAdjustmentData alloc] initWithFormatIdentifier:AdjustmentFormatIdentifier formatVersion:@"1.0" data:[@"CIAffineClamp" dataUsingEncoding:NSUTF8StringEncoding]];
/*
Create a PHContentEditingOutput object and write a JPEG representation
of the filtered object to the renderedContentURL.
*/
PHContentEditingOutput *contentEditingOutput = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.appliedFilter.editingInput];
NSData *jpegData = [self.appliedFilter.outputImage aapl_jpegRepresentationWithCompressionQuality:0.9f];
[jpegData writeToURL:[contentEditingOutput renderedContentURL] atomically:YES];
[contentEditingOutput setAdjustmentData:adjustmentData];
if ([self.appliedFilter.filterName isEqualToString:@"CIGaussianBlur"]) {
[contentEditingOutput setAdjustmentData:affineClamp];
}
// Ask the shared PHPhotoLinrary to perform the changes.
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *request = [PHAssetChangeRequest changeRequestForAsset:self.photo.asset];
request.contentEditingOutput = contentEditingOutput;
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
NSLog(@"Error: %@", error);
}
}];
// G: just pop to the view controller next to root, which is the Camera View Controller in Photo Mode.
[self.navigationController popToViewController:self.navigationController.viewControllers[1] animated:YES];
}
}
同样,如果我只有一个过滤器要应用,那么保存数据部分代码的工作非常好。同样,我的问题是当有两个过滤器应用时,如何调整数据。非常感谢你。我相信我的问题很清楚期待您的回答。首先,我不知道如何重新声明*过滤器而不出现错误(必须首先在您的控制结构之外声明,然后在内部重新声明) 下面是一个简单的例程,它将应用模糊并返回一个包含所需范围的图像
- (CIImage*)blurImage:(CIImage*)sourceImage withRadius:(NSNumber*)blurRadius {
CGRect originalExtent = sourceImage.extent;
CIImage *clampedImaged = [sourceImage imageByClampingToExtent];
CIImage *blurredImage = [clampedImaged imageByApplyingFilter:@"CIGaussianBlur" withInputParameters:@{@"inputRadius" : blurRadius}];
return [blurredImage imageByCroppingToRect:originalExtent];
}
否则,我无法告诉您originalImage或inputImageForFilter指的是什么,因此很难指出挂起的位置。您可以逐行调试此文件,并使用Xcode的peek功能(眼球图标)确保从每个过滤器生成的CIImage对象符合您的预期。首先,我不知道如何重新声明*过滤器而不出错(必须首先在控制结构外部声明,然后在内部重新声明) 下面是一个简单的例程,它将应用模糊并返回一个包含所需范围的图像
- (CIImage*)blurImage:(CIImage*)sourceImage withRadius:(NSNumber*)blurRadius {
CGRect originalExtent = sourceImage.extent;
CIImage *clampedImaged = [sourceImage imageByClampingToExtent];
CIImage *blurredImage = [clampedImaged imageByApplyingFilter:@"CIGaussianBlur" withInputParameters:@{@"inputRadius" : blurRadius}];
return [blurredImage imageByCroppingToRect:originalExtent];
}
否则,我无法告诉您originalImage或inputImageForFilter所指的是什么,因此很难建议挂起的位置。您可以逐行调试此代码并使用Xcode的peek功能(眼球图标)确保从每个过滤器生成的CIImage对象符合您的期望。谢谢您的回答。是的,我犯了一个错误,创建了一个新的CIFilter对象。无论如何,我想知道的是如何将图像保存为相集。好的,那么您的保存例程在哪里?保存部分在我的doneButtonAction方法中。比如什么我说过,当我一次只应用一个过滤器时,该方法可以很好地工作。例如:Posterize filter。它会在调用该方法时提示用户是否要修改照片。但是,当我使用CIAffineClamp应用模糊时,它会在完成处理程序中给我以下错误:-error Domain=NSCOCAerorDomain Code=-1”(null)这可能与您的保存例程无关,更多的是与您如何使用过滤器有关。我的意思是,将两个简单的过滤器链接在一起(如CiColorControl和CIColorInvert)看看会发生什么。谢谢你的回答。是的,我犯了一个错误,创建了一个新的CIFilter对象。不管怎样,我想知道的是如何将图像保存为PHAsset。好的,那么你的保存例程在哪里发生故障了?保存部分在我的doneButtonAction方法中。正如我所说的,当我一次只应用一个过滤器时,该方法工作正常。例如:Posterize Filter。它会在调用该方法时提示用户是否要修改照片。但是,当我使用CIAffineClamp应用模糊时,它会在完成处理程序中提示我此错误:-error Domain=nscocaerorDomain Code=-1”(null)这可能与您的保存例程无关,更多的是与您如何使用过滤器有关。我的意思是,将两个简单的过滤器链接在一起(如CiColorControl和CIColorInvert),看看会发生什么。