I want to crop a part of an uiimageview that on my view controller. I'm creating a rectangle on top of it:
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(context, newPoint1.x, newPoint1.y);
CGContextAddLineToPoint(context, newPoint1.x, newPoint2.y);
CGContextAddLineToPoint(context, newPoint2.x, newPoint2.y);
CGContextAddLineToPoint(context, newPoint2.x, newPoint1.y);
CGContextAddLineToPoint(context, newPoint1.x, newPoint1.y);
CGContextClosePath(context);
UIColor *blue = [UIColor colorWithRed: (0.0/255.0 ) green: (0.0/255.0) blue: (255.0/255.0) alpha:0.4];
CGContextSetFillColorWithColor(context, blue.CGColor);
CGContextDrawPath(context, kCGPathFillStroke);
I can't figure out how to crop it right. I'm able to retrieve a capture of the screen : entirely blank with my rectangle on it:
UIImage *cropImage = UIGraphicsGetImageFromCurrentImageContext();
rectImage = cropImage;
UIGraphicsEndImageContext();
UIImageCrop *rectImageView = [[UIImageCrop alloc]initWithImage:rectImage];
[self.view addSubview:rectImageView];
So I'm aware that there is something I've missed about it, any help?
- (UIImage *)captureScreenInRect:(CGRect)captureFrame
{
CALayer *layer;
layer = self.view.layer;
UIGraphicsBeginImageContext(self.view.frame.size);
CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenImage;
}
this is just for reference change this code according to your requirement
hope this will help you
You can get cropped image using :
- (UIImage*) getCroppedImage {
CGRect rect = PASS_YOUR_RECT;
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// translated rectangle for drawing sub image
CGRect drawRect = CGRectMake(-rect.origin.x, -rect.origin.y, your_image.size.width, your_image.size.height);
// clip to the bounds of the image context
// not strictly necessary as it will get clipped anyway?
CGContextClipToRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height));
// draw image
[your_image drawInRect:drawRect];
// grab image
UIImage* croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return croppedImage;
}
Hope it helps you.
Related
I need to take a UIImage and to add a semi-transparent layer in order to produce a new UIImage. I think I'm getting close but something is still wrong. Here's my code:
- (UIImage*) addLayerTo:(UIImage*)source
{
CGSize size = [source size];
UIGraphicsBeginImageContext(size);
CGRect rect = CGRectMake(0, 0, size.width, size.height);
[source drawInRect:rect blendMode:kCGBlendModeNormal alpha:0.18];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 0.2, 0.5, 0.1, 0.18);
CGContextFillRect(context, rect);
UIImage *testImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return testImg;
}
You forgot to draw the current image you want to blend with source image in current context.
- (UIImage*) addLayerTo:(UIImage*)source
{
CGSize size = [source size];
UIGraphicsBeginImageContext(size, NO, [UIScreen mainScreen].scale); // Use this image context initialiser instead
CGRect rect = CGRectMake(0, 0, size.width, size.height);
[self drawInRect: rect] // Draw the current image in context
[source drawInRect:rect blendMode:kCGBlendModeNormal alpha:0.18]; // Blend with other image
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, 0.2, 0.5, 0.1, 0.18);
CGContextFillRect(context, rect);
UIImage *testImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return testImg;
}
- (UIImage*) addLayerTo:(UIImage*)source
{
CGSize size = [source size];
// create context with UIScrean scale
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
// get new context
CGContextRef ctx1 = UIGraphicsGetCurrentContext();
// draw view
CGContextDrawImage(ctx1, CGRectMake(0.0f, 0.0f, size.width, size.height), source.CGImage);
// set fill color
UIColor *fillColor = [UIColor purpleColor];
// fill with it
CGContextSetFillColorWithColor(ctx1, fillColor.CGColor);
CGContextFillRect(ctx1, CGRectMake(0, 0, size.width, size.height));
// create new image
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
// end context
UIGraphicsEndImageContext();
return outputImage;
}
I have two images, one is a mask that is transparent with some edges / borders and the other is the actual image. I want to merge both of them.
I have used the following code to mask and combine the image:
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
// create a bitmap graphics context the size of the image
CGFloat dim = MIN(image.size.width, image.size.height);
CGSize size = CGSizeMake(dim, dim);
UIGraphicsBeginImageContextWithOptions(size, NO, .0);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:(CGRect){ CGPointZero, size }];
[bezierPath fill];
[bezierPath addClip];
CGPoint offset = CGPointMake((dim - image.size.width) * 0.5, (dim - image.size.height) * 0.5);
[image drawInRect:(CGRect){ offset, image.size }];
UIImage *ret = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return ret;
}
The result:
In the result image, the border of the image used as a mask is missing. Can someone please help me with this?
I wrote a masking category for ios (well it is basically cross platform because CoreImage is on both platforms anyway:
github project
the core functionality boils down to this (for your example)
UIImage *person = ...
UIImage *circle = ...
UIImage *result = [person imageMaskedWith:circle];
UIImageView *redbox = [[UIImageView alloc] initWithImage:result];
redbox.backgroundColor = [UIColor redColor]; //this can be a gradient!
the main part of the code from the category:
CGImageRef imageReference = image.CGImage;
CGImageRef maskReference = mask.CGImage;
CGRect rect = CGRectMake(0, 0, CGImageGetWidth(imageReference), CGImageGetHeight(imageReference));
// draw with Core Graphics
UIGraphicsBeginImageContext(rect.size);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(bitmap, 0.0, rect.size.height);
CGContextScaleCTM(bitmap, 1.0, -1.0);
CGContextClipToMask(bitmap, rect, maskReference);
CGContextDrawImage(bitmap, rect, imageReference);
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I'm currently coloring an existing image using a mask. For example, I have a white image with a black border and a circular mask (like the first two images). Then, I can create a third image with a color (i.e. green) which has green on the center of the original image (because the mask is present there).
The code I'm using is this (suggestions welcomed):
-(UIImage *)paintWithMask:(UIImage *)mask color:(UIColor *)color andSize:(CGSize)size{
UIImage *image = self;
UIImage *rotatedMask = [self rotateImage:mask]; //For some reason this is needed.
UIGraphicsBeginImageContextWithOptions(size, NO, image.scale);
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
[image drawInRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextClipToMask(context, rect, [rotatedMask CGImage]);
CGContextFillRect(context, rect);
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
What I need to do now is paint the green circle using only the mask (without the black border obviously), like this:
Any ideas? Thanks a lot!!
There is a much easier way of doing this without CoreGraphics. Simply do the following:
-(UIImageView *)imageViewWithMask:(UIImage *)mask color:(UIColor *)color andSize:(CGSize)size{
UIImage *tempImage = mask;
tempImage = [tempImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIGraphicsBeginImageContextWithOptions(size, NO,0);
[tempImage drawInRect: CGRectMake(0,0,size.width,size.height)];
tempImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *iv = [[UIImageView alloc] initWithImage: tempImage];
iv.tintColor = color;
return iv;
}
I want to draw a image for example on black canvas, but the the result is always white, here is my code
-(UIImage*) renderImage
{
UIGraphicsBeginImageContext(CGSizeMake(300, 300));
[[UIColor blackColor] setFill];
UIImage*resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultImage;
}
for the future i will draw an image inside the canvas, but right now i just want a black filled canvas. why this code is not working
You need to be using CGContextSetFillColorWithColor() to fill the current context with a color. Try this sample code, you give it a color and a size and it will return you a UIImage meeting your criteria.
- (UIImage *)renderImageWithColor:(UIColor *)color inSize:(CGSize)size
{
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
I'm trying to change the color of an image at runtime. I've seen a couple answers on SO, but they all change the background color and not the foreground, which is what I am trying to do. I've based my code on another SO thread.
Here's the code I have:
#implementation UIImage (Coloring)
-(UIImage*) imageWithColorOverlay:(UIColor*)color
{
//create context
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
// drawingcode
//bg
CGRect rect = CGRectMake(0.0, 0.0, self.size.width, self.size.height);
[self drawInRect:rect];
//fg
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//end
return image;
}
#end
This are the results thus far:
From left to right:
No blending, just the normal asset. The gray bg is from the UIView behind the imageviews, the bg of the image is transparent.
Multiply with kCGBlendModeMultiply
Color burn with kCGBlendModeColorBurn
Is there an CGBlendMode that'll achieve replacing the foreground color? Also, is it possible to replace both the foreground color(white) and the shadow(black)?
After messing around with the different blend options, this code did the trick. The only caveat is that the red tint is shown in the shadow, its not technically correct but its close enuf
#implementation UIImage (Coloring)
-(UIImage*) imageWithColorOverlay:(UIColor*)color
{
//create context
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
//drawingcode
//bg
CGRect rect = CGRectMake(0.0, 0.0, self.size.width, self.size.height);
[self drawInRect:rect];
//fg
CGContextSetBlendMode(context, kCGBlendModeMultiply);
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillRect(context, rect);
//mask
[self drawInRect:rect blendMode:kCGBlendModeDestinationIn alpha:1.0];
//end
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}