Multiply image and color - ios

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.

Related

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.

Reset button to original image from filtered image

I tried to add filters to my image in image view, when i tried to click on filter buttons they are stacking. Can you help me to create a reset or undo button to go to original image with iam getting original image from camera and camera roll?
(IBAction)filter:(id)sender {
CIContext *context=[CIContext contextWithOptions:nil];
CIImage *image =[CIImage imageWithCGImage:imageview.image.CGImage];
CIFilter *filter =[CIFilter filterWithName:#"CISepiaTone"];
[filter setValue:image forKey:kCIInputImageKey];
[filter setValue:#1.0f forKey:#"InputIntensity"];
CIImage *result =[filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage =[context createCGImage:result fromRect:result.extent];
UIImage *uiImage =[[UIImage alloc]initWithCGImage:cgImage];
[self.imageview setImage:uiImage];
Your filters are stacking because you're modifying the image in the imageview, and then putting that modified image back into the imageview. You should store your original image in a separate property and always start your modifications from that. For example, a property like:
#property (nonatomic, strong) UIImage *originalImage;
Then in your method, use the original image instead of the one already in the image view:
CIImage *image = [CIImage imageWithCGImage:self.originalImage.CGImage];
Storing data in member variables/properties is also just better practice than storing data in the view.

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

OpenCV:image processing,objective C/C++

My goal is to find golf ball using iPhone camera, So I did same steps in photoshop and
I want to achieve same steps in openCV on image/live video frame
start with the original picture.
then boost the satturation to get color into light areas
the use curves to cut off the edges of the spectrum
then convert the image to grayscale
use curves again to get to black/white
and finally - just for the look - apply a color
--Input Image:
--Output Image:
Would you please help me or give me some hints related image processing with OpenCV in iOS?
Thanks in advance!
Edit
I used following code and got the below output Image,
- (UIImage*) applyToneCurveToImage:(UIImage*)image
{
CIImage* ciImage = [[CIImage alloc] initWithImage:image];
CIFilter* filter =
[CIFilter filterWithName:#"CIToneCurve"
keysAndValues:
kCIInputImageKey, ciImage,
#"inputPoint0",[CIVector vectorWithX:0.00 Y:0.3]
,#"inputPoint1",[CIVector vectorWithX:0.25 Y:0.4]
,#"inputPoint2",[CIVector vectorWithX:0.50 Y:0.5]
,#"inputPoint3",[CIVector vectorWithX:0.75 Y:0.6]
,#"inputPoint4",[CIVector vectorWithX:1.00 Y:0.7]
,nil];
//CIFilter* filter2 = [filter copy];
//step1
filter = [CIFilter filterWithName:#"CIColorControls"
keysAndValues:kCIInputImageKey,
[filter valueForKey:kCIOutputImageKey], nil];
[filter setValue:[NSNumber numberWithFloat:0]
forKey:#"inputBrightness"];
[filter setValue:[NSNumber numberWithFloat:6]
forKey:#"inputContrast"];
CIImage* result = [filter valueForKey:kCIOutputImageKey];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:result
fromRect:[result extent]];
UIImage* filteredImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
ciImage=nil;
context=nil;
cgImage=nil;
result=nil;
return filteredImage;
}
- (void)didCaptureIplImage:(IplImage *)iplImage
{
#autoreleasepool
{
IplImage *orgimage = cvCreateImage(cvGetSize(iplImage), IPL_DEPTH_8U, 3);
orgimage=[self CreateIplImageFromUIImage:[self applyToneCurveToImage:[UIImage imageNamed:#"GolfImage.jpeg"] ] ];
Mat matRGB = Mat(orgimage);
//ipl imaeg is also converted to HSV; hue is used to find certain color
IplImage *imgHSV = cvCreateImage(cvGetSize(orgimage), 8, 3); //2
cvCvtColor(orgimage, imgHSV, CV_BGR2HSV);
IplImage *imgThreshed = cvCreateImage(cvGetSize(orgimage), 8, 1); //3
// cvInRangeS(imgHSV, cvScalar(_Hmin, _Smin, _Vmin), cvScalar(_Hmax , _Smax, _Vmax), imgThreshed);
cvInRangeS(imgHSV, cvScalar(0.00, 0.00, 34.82), cvScalar(180.00 , 202.54, 256.00), imgThreshed);
Originalimage=nil;
cvReleaseImage(&iplImage);
cvReleaseImage(&orgimage);
cvReleaseImage(&imgHSV);
[self didFinishProcessingImage:imgThreshed];
}
Output Image:
You don't need openCV for any of this. You should be able to get this result using Core Image
See this question How to change minimum or maximum value by CIFilter in Core image?
Where I give a fairly detailed answer on the manipulation of tone curves.
This will cover your steps 2 and 4. For step 1 (saturation) try CIColorControls. For step 3 (convert to grayscale) you could also use CIColorControls, but that would involove dropping saturation to 0, not what you want. Instead you can use CIMaximumComponentor CIMinimumComponent. For step 5, you could use the result of 1-4 as a mask with a flat colour.
OpenCV will allow you to pick out the ball from the rest of the image (I guess this is what you want to achieve, you didn't mention it in your question). You can refer to this question:
How does the HoughCircle function works? I can't get it to work properly which I answered with an accompanying demo project: https://github.com/foundry/OpenCVCircles. You can pass the result of your Core Image processing in to openCV by converting to the openCV Mat format from UIImage (that linked project shows you how to do this).

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.

Resources