How to perform image processing in ios - ios

I have an image named myImage.jpg
I have to do the following animations to the image and put the final result in an imageView in iOS. The requirements are:
Resized to 262%.
Duplicate layer.
Flip vertical.
Align duplicate layer to the bottom of the first layer.
Apply Gaussian Blur (Value - 9) to duplicate layer.
Move the blurred layer (duplicated layer) 47px upward
Added Layer mask on blurred layer.
Applied Gradient to mask layer from black to white.
How to do these animations on the image. I have done flip vertical using
- (UIImage *) flipImage: (UIImage *) image {
UIImage *flippedImage = [UIImage imageWithCGImage:image.CGImage scale:image.scale orientation:UIImageOrientationDownMirrored];
return flippedImage;
}
and blur with following code:
CIFilter *filter = [CIFilter filterWithName:#"CIGaussianBlur"];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat:3.0f] forKey:#"inputRadius"];
How to create a mask and gradient and how to combine these images?

I solved the problem. by generating separate images for original image, flipped blurred image, top and bottom gradients and combine them by using
UIGraphicsBeginImageContext(size)
Method.

Related

When merging two images CISourceOverCompositing losing alpha for watermark

I am merging two images using CIImage filter CISourceOverCompositing
issue is it is losing alpha/opacity of watermark/foreground image if its applied opacity is less than one.
I applied alpha value like this
CGFloat rgba[4] = {0.0, 0.0, 0.0, alphaVal};
CIFilter *colorMatrix = [CIFilter filterWithName:#"CIColorMatrix"];
I think issue is I need to change alpha from CIImage through some calculation as CIImage working space is not same as UIImage.
want these type of calculation for CIImage rgbs
Core Image filter CISourceOverCompositing not appearing as expected with alpha overlay

White pixels around iOS Image using CIFilter

I add a picture frame (Image with transparent background) around an existing UIImage and save it all as one image. On simulator, everything looks like it runs great. However on the device, it adds some white pixels around some of the areas of the frame's image. Here is my code:
- (void)applyFilter {
NSLog(#"Running");
UIImage *borderImage = [UIImage imageNamed:#"IMG_8055.PNG"];
NSData *dataFromImage = UIImageJPEGRepresentation(self.imgView.image, 1);
CIImage *beginImage= [CIImage imageWithData:dataFromImage];
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *border =[CIImage imageWithData:UIImagePNGRepresentation(borderImage)];
border = [border imageByApplyingTransform:CGAffineTransformMakeScale(beginImage.extent.size.width/border.extent.size.width, beginImage.extent.size.height/border.extent.size.height)];
CIFilter *filter= [CIFilter filterWithName:#"CISourceOverCompositing"]; //#"CISoftLightBlendMode"];
[filter setDefaults];
[filter setValue:border forKey:#"inputImage"];
[filter setValue:beginImage forKey:#"inputBackgroundImage"];
CIImage *outputImage = [filter valueForKey:#"outputImage"];
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg];
self.imgView.image = newImg;
}
Here is the resulting image:
The frame image used in the picture looks like this:
Here is a screenshot of the frame image in photoshop, showing those pixels are not present in the PNG.
The issue is that if you look at your image, those pixels immediately adjacent to the musical notes are apparently not transparent. And if you notice, those white pixels that appear in the final image aren't just the occasional pixel, but they appear in square blocks.
These sorts of squared-off pixel noise is a telltale sign of JPEG artifacts. It's hard to say what's causing this because the image you added to this question was a JPEG (which doesn't support transparency). I assume you must have a PNG version of this backdrop? You might have to share that with us to confirm this diagnosis.
But the bottom line is that you need to carefully examine the original image and the transparency of those pixels that appear to be white noise. Make sure that as you create/manipulate these images, avoid JPEG file formats, because it loses transparency information and introduces artifacts. PNG files are often safer.

Applying border to image shape

In my application I am having various images of different different shapes. Like tree, cloud. (Sample image is attached).
I want to add border to those shapes pro-grammatically. Like if image is of tree then need to highlight tree shape.
I cannot use calayer as it will apply border to UIImageView.
Can anyone guide me how to achieve this?
This can be achieved this by using a series of CIFilters. See images corresponding to steps below. In my example base image is a color image with transparent background and mask is black and white.
Use CIEdges to detect edges from the mask.
Then make edges thicker by applying disk maximum filter (CIMorphologyMaximum).
Convert borders image from black-and-white to transparent-and-white with CIMaskToAlpha
Overlay original image on top of borders.
Full code below:
let base = CIImage(cgImage: baseImage.cgImage!)
let mask = CIImage(cgImage: maskImage.cgImage!)
// 1
let edges = mask.applyingFilter("CIEdges", parameters: [
kCIInputIntensityKey: 1.0
])
// 2
let borderWidth = 0.02 * min(baseImage.size.width, baseImage.size.height)
let wideEdges = edges.applyingFilter("CIMorphologyMaximum", parameters: [
kCIInputRadiusKey: borderWidth
])
// 3
let background = wideEdges.applyingFilter("CIMaskToAlpha")
// 4
let composited = base.composited(over: background)
// Convert back to UIImage
let context = CIContext(options: nil)
let cgImageRef = context.createCGImage(composited, from: composited.extent)!
return UIImage(cgImage: cgImageRef)
Simple option is to draw the image twice, first with a small scale applied to grow the image a little. Masking if the images aren't transparent (but are black&white).
I just did the same thing but with a white border. I created a mask with a white body and 4px black stroke around the outside to give me the uniform border I want around my target image. The followng takes advantage of Core Image filters to mask off a solid color background (to be used as the border) and then to mask off and composite the target image.
// The two-tone mask image
UIImage *maskImage = [UIImage imageNamed: #"Mask"];
// Create a filler image of whatever color we want the border to be (in my case white)
UIGraphicsBeginImageContextWithOptions(maskImage.size, NO, maskImage.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, UIColor.whiteColor.CGColor);
CGContextFillRect(context, CGRectMake(0.f, 0.f, maskImage.size.width, maskImage.size.height));
UIImage *whiteImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Use CoreImage to mask the colored background to the mask (the entire opaque region of the mask)
CIContext *ciContext = [CIContext contextWithOptions: nil];
CIFilter *filter = [CIFilter filterWithName: #"CIBlendWithAlphaMask"];
[filter setValue: [CIImage imageWithCGImage: whiteImage.CGImage]
forKey: kCIInputImageKey];
[filter setValue: [CIImage imageWithCGImage: maskImage.CGImage]
forKey: kCIInputMaskImageKey];
CIImage *whiteBackground = filter.outputImage;
// scale the target image to the size of the mask (accounting for image scale)
// ** Uses NYXImageKit
image = [image scaleToSize: CGSizeMake(maskImage.size.width * maskImage.scale, maskImage.size.height * maskImage.scale)
usingMode: NYXResizeModeAspectFill];
// finally use Core Image to create our image using the masked white from above for our border and the inner (white) area of our mask image to mask the target image before compositing
filter = [CIFilter filterWithName: #"CIBlendWithMask"];
[filter setValue: [CIImage imageWithCGImage: image.CGImage]
forKey: kCIInputImageKey];
[filter setValue: whiteBackground
forKey: kCIInputBackgroundImageKey];
[filter setValue: [CIImage imageWithCGImage: maskImage.CGImage]
forKey: kCIInputMaskImageKey];
image = [UIImage imageWithCGImage: [ciContext createCGImage: filter.outputImage
fromRect: [filter.outputImage extent]]];
You can apply border to objects present in the image using OpenCV framework.
Check this link. Here edges are detected of an image and border is applied to it. I hope this will give exact idea which you want.
https://github.com/BloodAxe/OpenCV-Tutorial

I am using CIFilter to get a blur image,but why is the output image always larger than input image?

Codes are as below:
CIImage *imageToBlur = [CIImage imageWithCGImage: self.pBackgroundImageView.image.CGImage];
CIFilter *blurFilter = [CIFilter filterWithName: #"CIGaussianBlur" keysAndValues: kCIInputImageKey, imageToBlur, #"inputRadius", [NSNumber numberWithFloat: 10.0], nil];
CIImage *outputImage = [blurFilter outputImage];
UIImage *resultImage = [UIImage imageWithCIImage: outputImage];
For example,the input image has a size of (640.000000,1136.000000),but the output image has a size of (700.000000,1196.000000)
Any advice is appreciated.
This is a super late answer to your question, but the main problem is you're thinking of a CIImage as an image. It is not, it is a "recipe" for an image. So, when you apply the blur filter to it, Core Image calculates that to show every last pixel of your blur you would need a larger canvas. That estimated size to draw the entire image is called the "extent". In essence, every pixel is getting "fatter", which means that the final extent will be bigger than the original canvas. It is up to you to determine which part of the extent is useful to your drawing routine.

Multiply image and color

I have an image with transparence background, for example image.
I need to create many images with different color and I want to use this one image and multiply it with color for create some other images, for example new image.
Could you please help me with some lines of code. Thanks.
This might help:
UIImage *beginUIImage = [UIImage imageNamed:#"myImage.png"];
CIImage *beginImage = [CIImage imageWithCGImage:beginUIImage.CGImage];
CIFilter *filter = [CIFilter filterWithName:#"CISepiaTone"
keysAndValues: kCIInputImageKey, beginImage,
#"inputIntensity", [NSNumber numberWithFloat:0.8], nil];
CIImage *outputImage = [filter outputImage];
UIImage *endImage = [[UIImage alloc] initWithCIImage:outputImage];
The beginUIImage is the initial transparent image. Then I change it into a CIImage to ease the process of applying filters. Then I apply a Sepia filter to the image. Then I output the image with a filter applied into another CIImage called outputImage. Lastly, I change the outputImage into a UIImage to be used later, perhaps put into a UIImageView, perhaps saved into the Photo library. You can change the type of filter to change the output images' colors.

Resources