Core Graphics Circular Image Blurry - ios

I'm drawing a circle image using core graphics with a modified implementation of this SO answer
Here's my source:
+ (UIImage*)circularImageWithRadius:(CGFloat)radius color:(UIColor*)color{
CGRect rect = CGRectMake(0.0f, 0.0f, radius*2, radius*2);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillEllipseInRect(context, rect);
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
The edges are blurry and I'm not sure why (I thought it didn't matter what resolution the device was, it would work right out of the box).
I tried replacing CGContextFillEllipseInRect(context, rect); with CGContextFillRect(context, rect); and that was blurry too. Then I tried CGContextFillRect(context, CGRectMake(0, 0, radius*4, radius*4) and it works perfectly, sharp image and everything (albeit being a a square, not a circle). So I changed back to CGContextDrawEllipseInRect(context, CGRectMake(0, 0, radius*4, radius*4) but this was my result:
whereas with the rectangle, it was the same size as when using radius*2 but with a much sharper image.
How can I fix my blurry issue and why does CGContextFillEllipseInRect not fill the pre-defined image rect?

I feel dumb for having found this immediately after I posted but this answer pointed the way.
I just added
if(UIGraphicsBeginImageContextWithOptions != NULL) {
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);
} else {
UIGraphicsBeginImageContext(rect.size);
}
instead of just UIGraphicsBeginImageContext(rect.size); into my original source and it's crystal clear and sharp.

For Swift 3.0
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
defer { UIGraphicsEndImageContext() }
if let context = UIGraphicsGetCurrentContext() {
/// Do Stuff
}

Related

circle image created by objective-c code has always been clipped

I was researching how to make a circle image by code in objective-c these two days. I found several way to do this, but no matter which way, the image created is not an exact circle, which is cut. Please see following code and image:
CGRect rect = CGRectMake(0.0f, 0.0f, radius*2.0f, radius*2.0f);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillEllipseInRect(context, rect);
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
If you look at the image carefully, you will find that the edge has been cut.
Finally I found if I change the code as following:
CGRect rect = CGRectMake(0.0f, 0.0f, radius*2.0f+4, radius*2.0f+4);
CGRect rectmin = CGRectMake(2.0f, 2.0f, radius*2, radius*2);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillEllipseInRect(context, rectmin);
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
The result is much better, but I don't think it's a nice solution. Does anybody know exactly what's the problem of my first code snippet? Thanks in advance.
p.s. all the screenshots are captured from the simulator.

Color tinted UIImages gets pixelated

I am having problem understanding the reason for the following method, to return images that are visibly pixelated. I have double checked the size of the image, and it is fine. What's more, without tinting it, the image edges are smooth, and lack pixelation.
The method for tinting image, based on IOS7 ImageView's tintColor property, works fine, however I would love to find out what is wrong with the following code, because it seems to work for everybody but me. Thanks!
- (UIImage *)imageTintedWithColor:(UIColor *)color
{
if (color) {
UIImage *img = self; // The method is a part of UIImage category, hence the "self"
UIGraphicsBeginImageContext(img.size);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
// set the fill color
[color setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, img.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height);
CGContextDrawImage(context, rect, img.CGImage);
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextSetBlendMode(context, kCGBlendModeSourceIn);
CGContextAddRect(context, rect);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return the color-burned image
return coloredImg;
}
return self;
}
Change this line:
UIGraphicsBeginImageContext(img.size);
to:
UIGraphicsBeginImageContextWithOptions(img.size, NO, 0);
If your images will never have an transparency, change the NO to YES.

Color overlay on specific area of UIImage

I'm trying to overlay a color on a UIImage, but only on the left half of the image (I'm using code from http://coffeeshopped.com/2010/09/iphone-how-to-dynamically-color-a-uiimage to overlay the color). The code I have now is:
- (UIImage *)imageWithColor:(UIColor *)color{
// begin a new image context, to draw our colored image onto
CGSize size = CGSizeMake(self.line.image.size.width/2, self.line.image.size.height);
UIGraphicsBeginImageContextWithOptions(size, NO, [[UIScreen mainScreen] scale]);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
// set the fill color
[color setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to overlay, and the original image
CGContextSetBlendMode(context, kCGBlendModeOverlay);
CGRect rect = CGRectMake(0, 0, size.width, size.height);
CGContextDrawImage(context, rect, self.line.image.CGImage);
// set a mask that matches the shape of the image, then draw (overlay) a colored rectangle
CGContextClipToMask(context, rect, self.line.image.CGImage);
CGContextAddRect(context, rect);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return the color-burned image
return coloredImg;
}
I thought setting the size to be half the width would work, but everything still gets color. I guess I'm missing something very fundamental. Any ideas?
In
CGContextAddRect(context, rect);
you are adding a rectangle with the full size.

Why is my image upside down after using CGContextSetFillColorWithColor

I am trying to apply a color fill to the MKAnnotation. I found some code that pretty much works but for some reason the filled image is upside down after applying the fill to it.
Here is the current code that I am running on a map pin.
CGRect rect = CGRectMake(0, 0, self.image.size.width, self.image.size.height);
UIGraphicsBeginImageContext(self.image.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToMask(context, rect, self.image.CGImage);
CGContextSetFillColorWithColor(context, [[UIColor grayColor] CGColor]);
CGContextFillRect(context, rect);
CGContextRotateCTM(context, 90);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *flippedImage = [UIImage imageWithCGImage:img.CGImage
scale:1.0 orientation:self.image.imageOrientation];
self.image = flippedImage;
Here is what the pins look like after this code runs.
http://d.pr/i/UaPU
I was thinking that if I applied the current image orientation to the flippedImage that would do the trick but that did not work. I also tried setting self.image = img; and removing the flippedImage var completely but the result is still the same.
CGContext coordinate system is flipped vertically in regard to UIView coordinate system.
Just flip it like this:
CGContextTranslateCTM(ctx, 0, imageHeight);,
CGContextScaleCTM(ctx, 1, -1);

scale and crop image ios

I'm working in a function for scaling and crop image (similar to camara app) for iOS, the code below works fine, just that the resulting image came up side down, and I would like to understand why.
Thanks
- (UIImage*)imageByCropping:(UIImageView *)imageViewToCrop toRect:(CGRect)rect
{
//create a context to do our clipping in
CGRect newRect = CGRectApplyAffineTransform(rect, imageViewToCrop.transform);
UIImage *imageToCrop = imageViewToCrop.image;
UIGraphicsBeginImageContext(newRect.size);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
//create a rect with the size we want to crop the image to
//the X and Y here are zero so we start at the beginning of our
//newly created context
CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height);
CGContextClipToRect( currentContext, clippedRect);
//draw the image to our clipped context using our offset rect
CGContextDrawImage(currentContext, newRect, imageToCrop.CGImage);
//pull the image from our cropped context
UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();
//pop the context to get back to the default
UIGraphicsEndImageContext();
return cropped;
}
I've also came across this issue without explanation. But have found a workaround that solves that problem. Just put the following two lines in your code and try it again. It works for me.
CGContextTranslateCTM(context, 0.0, newRect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);//flip context

Resources