Before Applying filter Image
After applying Red Eye filter, get bad output image
Output Image is different every time.
Here is the code of my red eye correction filter
UIImage *img = self.imageInput;
CIImage *image = [[CIImage alloc]initWithImage:img];
NSLog(#"after ciimage: %#", kCIImageAutoAdjustEnhance);
NSDictionary *options = [NSDictionary dictionaryWithObject:#"NO" forKey:kCIImageAutoAdjustEnhance];
NSLog(#"options: %#", options);
NSArray *adjustments = [image autoAdjustmentFiltersWithOptions:options];
NSLog(#"adjustments: %# ", adjustments);
for (CIFilter * filter in adjustments)
{
[filter setValue:image forKey:kCIInputImageKey];
image = filter.outputImage;
}
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:image fromRect:image.extent];
UIImage *enhancedImage = [[UIImage alloc] initWithCGImage:cgImage];
CGImageRelease(cgImage);
self.imageViewSource.image = enhancedImage;
Related
I am using CIFilter for image filtering in my iOS app.My following code works smoothly.But i have one problem,i think processing of image is time taken(I can’t get real time effect).How to solve this issue?
cameraImgView.image = [ImageProcessing sepian:myOriginalImage withInensity:0.5]; //method call
Method Definition
+(UIImage*)sepian:(UIImage*)img withInensity:(float)intensity{
CIImage *cimage = [[CIImage alloc] initWithImage:img];
CIFilter *sepiaFilter = [CIFilter filterWithName:#"CISepiaTone"];
[sepiaFilter setDefaults];
[sepiaFilter setValue:cimage forKey:#"inputImage"];
[sepiaFilter setValue:[NSNumber numberWithFloat:intensity]
forKey:#"inputIntensity"];
CIImage *outputImage = [sepiaFilter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:
outputImage fromRect:[outputImage extent]];
UIImage *resultUIImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
return resultUIImage;
}
Try this:
filter = [CIFilter filterWithName:#"CISepiaTone"
keysAndValues: kCIInputImageKey, rawImageData,
#"inputIntensity", #3.5, nil];
Give this filter like below:
CIImage *filteredImageData = [filter valueForKey:#"outputImage"];
UIImage *filteredImage = [UIImage imageWithCIImage:filteredImageData];
self.img_view.image = filteredImage;
My app is crashing when I attempt to apply a filter to my user-selected UIImage (It has been working fine without applying the filter). I added and imported the "CoreImage" framework to my project so I could create filters for user-selected images.
I am attempting to apply the filter by creating a category for UIImage (based on Apple's documentation, and then calling the corresponding method on the UIImage selected by the user. Following is the code of my category header and body; what am I doing wrong? (please note, "randColor" is a category UIColor class method to generate a random color)
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
#import "UIColor+CustomColorCategory.h"
#interface UIImage (MonoChromeFilter)
- (UIImage *) applyMonoChromeWithRandColor;
#end
#import "UIImage+MonoChromeFilter.h"
#implementation UIImage (MonoChromeFilter)
- (UIImage *)applyMonoChromeWithRandColor
{
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *ciImage = [[CIImage alloc] initWithImage:self];
CIFilter *filter = [CIFilter filterWithName:#"CIColorMonochrome"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:[UIColor randColor] forKey:kCIAttributeTypeColor];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGRect extent = [result extent];
CGImageRef cgImage = [context createCGImage:result fromRect:extent];
UIImage *filteredImage = [[UIImage alloc] initWithCGImage:cgImage];
return filteredImage;
}
#end
Here is the method in the viewController where this category is being called:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:^{
UIImage *editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
editedImage = [editedImage applyMonoChromeWithRandColor];
self.blogImageOutlet.image = editedImage;
self.blogImageOutlet.layer.cornerRadius = self.blogImageOutlet.frame.size.width / 2.0;
[self.blogImageOutlet setClipsToBounds:YES];
[self saveImageToLibrary:editedImage];
}];
}
I figured it out! After debugging and using some other projects as a point of reference, I realized that I was experiencing two issues. First, I was trying to use a UIColor for CIColor, which is not directly possible. I first had to covert the UIColor to a CIColor to be able to apply it. Next, I was not using the correct strings for the CIFilter value keys. Here is the following code after modifications (and now it works!)
#import "UIImage+MonoChromeFilter.h"
#implementation UIImage (MonoChromeFilter)
+ (UIImage *) applyMonoChromeWithRandColor: (UIImage *)uIImage
{
// Convert UIColor to CIColor
CGColorRef colorRef = [UIColor randColor].CGColor;
NSString *colorString = [CIColor colorWithCGColor:colorRef].stringRepresentation;
CIColor *coreColor = [CIColor colorWithString:colorString];
CIContext *context = [CIContext contextWithOptions:nil];
// Convert UIImage to CIImage
CIImage *ciImage = [[CIImage alloc] initWithImage:uIImage];
// Set values for CIColorMonochrome Filter
CIFilter *filter = [CIFilter filterWithName:#"CIColorMonochrome"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:#1.0 forKey:#"inputIntensity"];
[filter setValue:coreColor forKey:#"inputColor"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGRect extent = [result extent];
CGImageRef cgImage = [context createCGImage:result fromRect:extent];
UIImage *filteredImage = [[UIImage alloc] initWithCGImage:cgImage];
return filteredImage;
}
#end
Try This , It's work like champs for me ,
We have applied different CIFilter for single image,
Below is code for implementation ,
//CISepiaTone Effect,
CIContext *imageContext = [CIContext contextWithOptions:nil];
CIImage *image = [[CIImage alloc]initWithImage:inputimage];
CIFilter *filter = [CIFilter filterWithName:#"CISepiaTone"
keysAndValues: kCIInputImageKey, image,
#"inputIntensity", #1, nil];
CIImage *result = [filter valueForKey: #"outputImage"];
CGImageRef cgImageRef = [imageContext createCGImage:result fromRect:[result extent]];
UIImage *targetImage = [UIImage imageWithCGImage:cgImageRef];
detailsVc.filterImage=targetImage;
[self.navigationController pushViewController:detailsVc animated:YES];
//CIVignette Effect
CIContext *imageContext = [CIContext contextWithOptions:nil];
CIImage *image = [[CIImage alloc] initWithImage:inputimage];
CIFilter *vignette = [CIFilter filterWithName:#"CIVignette"];
[vignette setDefaults];
[vignette setValue: image forKey: #"inputImage"];
[vignette setValue: [NSNumber numberWithFloat: 1.0] forKey: #"inputIntensity"];
[vignette setValue: [NSNumber numberWithFloat: 10.00 ] forKey: #"inputRadius"];
CIImage *result = [vignette valueForKey: #"outputImage"];
CGImageRef cgImageRef = [imageContext createCGImage:result fromRect:[result extent]];
UIImage *targetImage = [UIImage imageWithCGImage:cgImageRef];
detailsVc.filterImage=targetImage;
[self.navigationController pushViewController:detailsVc animated:YES];
For detail implementation you can refer this GitHub project file ImageFilter
Hope so This will help for some one .
I have a UISlider which has a range from 0 to 30.
Unfortunately, when I'm using the UISlider, the image starts to blur, BUT it also rotates.
Here's the code:
-(IBAction)slider:(UISlider *)sender
{
float slideValue = [sender value];
CIImage *beginImage = [[CIImage alloc] initWithImage:image];
CIContext *context = [CIContext contextWithOptions:nil];
CIFilter *filter = [CIFilter filterWithName:#"CIGaussianBlur" keysAndValues:kCIInputImageKey, beginImage, #"inputRadius", [NSNumber numberWithFloat:slideValue], nil];
CIImage *outputImage = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[beginImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg];
[imageView setImage:newImg];
CGImageRelease(cgimg);
}
Where is the problem?
Thanks in advance.
The problem is this line:
UIImage *newImg = [UIImage imageWithCGImage:cgimg];
This is too simple-minded. Call [UIImage imageWithCGImage:cgimg scale:originalScale orientation:originalOrientation]; (you will need to provide correct values for these).
I'm using the below method to blur some images. Using instruments the CIImage's are leaking. I tried wrapping them in an #autoreleasepool, but no luck. Any ideas?
-(UIImage *)blurImage:(UIImage *)image withStrength:(float)strength
{
#autoreleasepool {
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [[CIImage alloc] initWithCGImage:image.CGImage];
CIFilter *filter = [CIFilter filterWithName:#"CIGaussianBlur"];
[filter setValue:inputImage forKey:#"inputImage"];
[filter setValue:[NSNumber numberWithFloat:strength] forKey:#"inputRadius"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
float scale = [[UIScreen mainScreen] scale];
CIImage *cropped=[result imageByCroppingToRect:CGRectMake(0, 0, image.size.width*scale, image.size.height*scale)];
CGRect extent = [cropped extent];
CGImageRef cgImage = [context createCGImage:cropped fromRect:extent];
UIImage *returnImage = [UIImage imageWithCGImage:cgImage].copy;
CGImageRelease(cgImage);
return returnImage;
}
}
I see the same leak you're seeing when profiling the code. Try this instead which seems to avoid the leak and give you the same results:
- (UIImage*)blurImage:(UIImage*)image withStrength:(float)strength
{
#autoreleasepool {
CIImage* inputImage = [[CIImage alloc] initWithCGImage:image.CGImage];
CIFilter* filter = [CIFilter filterWithName:#"CIGaussianBlur"];
[filter setValue:inputImage forKey:#"inputImage"];
[filter setValue:[NSNumber numberWithFloat:strength] forKey:#"inputRadius"];
CIImage* result = [filter valueForKey:kCIOutputImageKey];
float scale = [[UIScreen mainScreen] scale];
CIImage* cropped = [result imageByCroppingToRect:CGRectMake(0, 0, image.size.width * scale, image.size.height * scale)];
return [[UIImage alloc] initWithCIImage:cropped];
}
}
did you try to put CIImages to nil ?
-(UIImage *)blurImage:(UIImage *)image withStrength:(float)strength
{
//your code
CGImageRelease(cgImage);
cropped=nil;
result = nil;
inputImage = nil;
context = nil;
return returnImage;
}
}
I'm working with filtering images that I'm taking with the camera. I pass the image I get from the camera through the below method. Which I have the returned UIImage sent to a UIImageView. For some reason when it passes through this method the image is getting rotated. What am I doing wrong?
- (UIImage *) applyFilterToImage:(UIImage *)image withFilter:(NSString *)filterName {
beginImage = [[[CIImage alloc] initWithImage:image] autorelease];
context = [CIContext contextWithOptions:nil];
filter = [CIFilter filterWithName:#"CISepiaTone" keysAndValues:kCIInputImageKey, beginImage, #"inputIntensity", [NSNumber numberWithFloat:0.8], nil];
outputImage = [filter outputImage];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg scale:1.0 orientation:UIImageOrientationUp];
CGImageRelease(cgimg);
return scaleAndRotateImage(newImg);
}