将滤镜应用于 CIImage [Core Image] 时获取 EXC_BAD_ACCESS
Getting EXC_BAD_ACCESS while Applying filter to CIImage [Core Image]
我正在处理 Imagebase 应用程序。我想在图像上应用一些过滤器。为此,我使用了 [Core Image]。
我在数组中存储了一些 FilterName 并显示过滤器效果作为预览我正在使用 UICollection 视图。当用户点击预览图像时,过滤器将应用于主图像视图。但是当我点击 preview cell 时,过滤器在 Main Imageview 上成功应用。但在那之后,当我拖动集合视图单元格以应用下一个预览时,我得到 BAD_ACCESS 过滤方法错误。
-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
这是我应用过滤器的代码:-
过滤器数组和 RegisterCollectionview 单元格的初始设置:-
-(void)setUpDefaultUI{
[self HideControlsAndSetupUI];
arrFilter = @[ @"Original",
@"CILinearToSRGBToneCurve",
@"CIPhotoEffectChrome",
@"CIPhotoEffectFade",
@"CIPhotoEffectInstant",
@"CIPhotoEffectMono",
@"CIPhotoEffectNoir",
@"CIPhotoEffectProcess",
@"CIPhotoEffectTonal",
@"CIPhotoEffectTransfer",
@"CISRGBToneCurveToLinear",
@"CIVignette",
// @"CIVignetteEffect",
@"CISepiaTone",
];
[self.vwCollection registerClass:[ActivityCollectionViewCell class] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
[self.vwCollection registerNib:[UINib nibWithNibName:@"ActivityCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
_imgEdit.image=_stillImage; // To apply filter on this Image
_OriginalImage=_stillImage; // Original image if user declined to use filter
}
CollectionView 数据源:-
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"filterAvailable");
ActivityCollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];
if (cell == nil) {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
cell = [xib objectAtIndex:0];
[cell.imgVw setContentMode:UIViewContentModeScaleAspectFill];
}
if (indexPath.item==0) {
cell.imgVw.image = _OriginalImage; //Original Image on 0 index
}else{
UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Apply filter on this method
cell.imgVw.image=img;
}
return cell;
}
Collectionview 委托:-
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
ActivityCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];
if (cell == nil) {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
cell = [xib objectAtIndex:0];
}
if (indexPath.item==0) {
_imgEdit.image=_OriginalImage; // Set original image in main Imageview
}else{
UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]];
_imgEdit.image = img; // Apply filter on Main Imageview
}
}
通过此方法应用过滤器:-
-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
{
UIImageOrientation originalOrientation = picture.imageOrientation;
CGFloat originalScale = picture.scale;
CIImage *beginImage = [CIImage imageWithCGImage:picture.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
CIImage *outputImage = [filter outputImage];
CGImageRef cgimg =
[context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg scale:originalScale orientation:originalOrientation];
//CGImageRelease(CGImageRef) method.
CGImageRelease(cgimg);
return newImg;
}
错误图片:-
- BAD_ACCESS
- 您确定
picture
是有效的 UIImage
对象吗?在 applyFilter:withFilterName:
的开头放置一个断点,并使用 Xcode 的快速查看来确认它是您认为的。
- 还要检查
Filtername
是否为有效字符串。
如果这些都是正确的,这看起来很可疑:
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
此处的键和值是一个以 nil 结尾的列表。尝试删除第一个 nil
:
之后的所有内容
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil];
另请注意,CIVignette
和 CISepiaTone
都有额外的输入参数(参见 Apple 的 Core Image Filter Reference)
终于找到问题了。实际上问题是,我在两种方法中都对静止图像应用过滤器。
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
和
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
所以,最终的解决方案是在两种方法中使用不同的图像。
这是代码:-
//初始设置
-(void)setUpDefaultUI{
[自己隐藏ControlsAndSetupUI];
arrFilter = @[ @"Original",
@"CILinearToSRGBToneCurve",
@"CIPhotoEffectChrome",
@"CIPhotoEffectFade",
@"CIPhotoEffectInstant",
@"CIPhotoEffectMono",
@"CIPhotoEffectNoir",
@"CIPhotoEffectProcess",
@"CIPhotoEffectTonal",
@"CIPhotoEffectTransfer",
@"CISRGBToneCurveToLinear",
@"CIVignette",
// @"CIVignetteEffect",
@"CISepiaTone",
];
[self.vwCollection registerClass:[ActivityCollectionViewCell class] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
[self.vwCollection registerNib:[UINib nibWithNibName:@"ActivityCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
_imgEdit.image=_stillImage;
_OriginalImage=_stillImage;
temp=_OriginalImage;
}
//Datasource 方法使用过滤器在集合视图中显示图像
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"filterAvailable");
ActivityCollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];
if (cell == nil) {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
cell = [xib objectAtIndex:0];
//[cell.imgVw setContentMode:UIViewContentModeScaleAspectFill];
cell.imgVw.clipsToBounds = YES;
cell.imgVw.layer.cornerRadius = 5;
}
if (indexPath.item==0) {
cell.imgVw.image = _OriginalImage; //Set original image of 1st index
}else{
UIImage *img=[self applyFilter:temp withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Set temp image in place of stilimage
cell.imgVw.image=img;
}
return cell;
}
//在主图像视图上应用滤镜。
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
if (_EnumPhotos==defaultPhotos) {
if (indexPath.item==0) {
_imgEdit.image=_OriginalImage; //If user click on 1st index then original filter applied on main image
}else{
UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Use still image here .
_imgEdit.image = img; // Apply image on main image view
}
}
}
//应用过滤方法
-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
{
UIImageOrientation originalOrientation = picture.imageOrientation;
CGFloat originalScale = picture.scale;
CIImage *beginImage = [CIImage imageWithCGImage:picture.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
CIImage *outputImage = [filter outputImage];
CGImageRef cgimg =
[context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg scale:originalScale orientation:originalOrientation];
//CGImageRelease(CGImageRef) method.
CGImageRelease(cgimg);
return newImg;
}
我正在处理 Imagebase 应用程序。我想在图像上应用一些过滤器。为此,我使用了 [Core Image]。
我在数组中存储了一些 FilterName 并显示过滤器效果作为预览我正在使用 UICollection 视图。当用户点击预览图像时,过滤器将应用于主图像视图。但是当我点击 preview cell 时,过滤器在 Main Imageview 上成功应用。但在那之后,当我拖动集合视图单元格以应用下一个预览时,我得到 BAD_ACCESS 过滤方法错误。
-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
这是我应用过滤器的代码:-
过滤器数组和 RegisterCollectionview 单元格的初始设置:-
-(void)setUpDefaultUI{
[self HideControlsAndSetupUI];
arrFilter = @[ @"Original",
@"CILinearToSRGBToneCurve",
@"CIPhotoEffectChrome",
@"CIPhotoEffectFade",
@"CIPhotoEffectInstant",
@"CIPhotoEffectMono",
@"CIPhotoEffectNoir",
@"CIPhotoEffectProcess",
@"CIPhotoEffectTonal",
@"CIPhotoEffectTransfer",
@"CISRGBToneCurveToLinear",
@"CIVignette",
// @"CIVignetteEffect",
@"CISepiaTone",
];
[self.vwCollection registerClass:[ActivityCollectionViewCell class] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
[self.vwCollection registerNib:[UINib nibWithNibName:@"ActivityCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
_imgEdit.image=_stillImage; // To apply filter on this Image
_OriginalImage=_stillImage; // Original image if user declined to use filter
}
CollectionView 数据源:-
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"filterAvailable");
ActivityCollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];
if (cell == nil) {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
cell = [xib objectAtIndex:0];
[cell.imgVw setContentMode:UIViewContentModeScaleAspectFill];
}
if (indexPath.item==0) {
cell.imgVw.image = _OriginalImage; //Original Image on 0 index
}else{
UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Apply filter on this method
cell.imgVw.image=img;
}
return cell;
}
Collectionview 委托:-
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
ActivityCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];
if (cell == nil) {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
cell = [xib objectAtIndex:0];
}
if (indexPath.item==0) {
_imgEdit.image=_OriginalImage; // Set original image in main Imageview
}else{
UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]];
_imgEdit.image = img; // Apply filter on Main Imageview
}
}
通过此方法应用过滤器:-
-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
{
UIImageOrientation originalOrientation = picture.imageOrientation;
CGFloat originalScale = picture.scale;
CIImage *beginImage = [CIImage imageWithCGImage:picture.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
CIImage *outputImage = [filter outputImage];
CGImageRef cgimg =
[context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg scale:originalScale orientation:originalOrientation];
//CGImageRelease(CGImageRef) method.
CGImageRelease(cgimg);
return newImg;
}
错误图片:-
- BAD_ACCESS
- 您确定
picture
是有效的UIImage
对象吗?在applyFilter:withFilterName:
的开头放置一个断点,并使用 Xcode 的快速查看来确认它是您认为的。 - 还要检查
Filtername
是否为有效字符串。
如果这些都是正确的,这看起来很可疑:
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
此处的键和值是一个以 nil 结尾的列表。尝试删除第一个 nil
:
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil];
另请注意,CIVignette
和 CISepiaTone
都有额外的输入参数(参见 Apple 的 Core Image Filter Reference)
终于找到问题了。实际上问题是,我在两种方法中都对静止图像应用过滤器。
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
和
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
所以,最终的解决方案是在两种方法中使用不同的图像。
这是代码:- //初始设置 -(void)setUpDefaultUI{ [自己隐藏ControlsAndSetupUI];
arrFilter = @[ @"Original",
@"CILinearToSRGBToneCurve",
@"CIPhotoEffectChrome",
@"CIPhotoEffectFade",
@"CIPhotoEffectInstant",
@"CIPhotoEffectMono",
@"CIPhotoEffectNoir",
@"CIPhotoEffectProcess",
@"CIPhotoEffectTonal",
@"CIPhotoEffectTransfer",
@"CISRGBToneCurveToLinear",
@"CIVignette",
// @"CIVignetteEffect",
@"CISepiaTone",
];
[self.vwCollection registerClass:[ActivityCollectionViewCell class] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
[self.vwCollection registerNib:[UINib nibWithNibName:@"ActivityCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"ActivityCollectionViewCell"];
_imgEdit.image=_stillImage;
_OriginalImage=_stillImage;
temp=_OriginalImage;
}
//Datasource 方法使用过滤器在集合视图中显示图像
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"filterAvailable");
ActivityCollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@"ActivityCollectionViewCell" forIndexPath:indexPath];
if (cell == nil) {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"ActivityCollectionViewCell" owner:self options:nil];
cell = [xib objectAtIndex:0];
//[cell.imgVw setContentMode:UIViewContentModeScaleAspectFill];
cell.imgVw.clipsToBounds = YES;
cell.imgVw.layer.cornerRadius = 5;
}
if (indexPath.item==0) {
cell.imgVw.image = _OriginalImage; //Set original image of 1st index
}else{
UIImage *img=[self applyFilter:temp withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Set temp image in place of stilimage
cell.imgVw.image=img;
}
return cell;
}
//在主图像视图上应用滤镜。
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
if (_EnumPhotos==defaultPhotos) {
if (indexPath.item==0) {
_imgEdit.image=_OriginalImage; //If user click on 1st index then original filter applied on main image
}else{
UIImage *img=[self applyFilter:_stillImage withFilterName:[arrFilter objectAtIndex:indexPath.row]]; // Use still image here .
_imgEdit.image = img; // Apply image on main image view
}
}
}
//应用过滤方法
-(UIImage *) applyFilter: (UIImage*) picture withFilterName:(NSString*)Filtername
{
UIImageOrientation originalOrientation = picture.imageOrientation;
CGFloat originalScale = picture.scale;
CIImage *beginImage = [CIImage imageWithCGImage:picture.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];
CIFilter *filter = [CIFilter filterWithName:Filtername keysAndValues: kCIInputImageKey, beginImage, nil, [NSNumber numberWithFloat:0.7], nil];
CIImage *outputImage = [filter outputImage];
CGImageRef cgimg =
[context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg scale:originalScale orientation:originalOrientation];
//CGImageRelease(CGImageRef) method.
CGImageRelease(cgimg);
return newImg;
}