I am trying to change the width and color of a rectangle that is drawn using CG. In the following function I am masking the image with a different color, but how do I change the width?
- (void)colorImage:(UIImage *)origImage withColor:(UIColor *)color withWidth:(float) width
{
UIImage *image = origImage;
NSLog(#"%f", width);
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, width);
CGContextClipToMask(context, rect, image.CGImage);
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImage *flippedImage = [UIImage imageWithCGImage:img.CGImage
scale:1.0 orientation: UIImageOrientationDownMirrored];
self.image = flippedImage;
}
You set the line width with CGContextSetLineWidth(context, width).
The reason why you're seeing no effect from this is because you aren't stroking anything. Line width applies to the line painted by stroking. You're filling, not stroking, and a fill has no line to give width to.
If you want to put a border around the rectangle, you need to stroke it. That's what draws a line all the way around the perimeter of some shape.
You have three options:
Call CGContextSetLineWidth, then CGContextStrokeRect.
Call CGContextStrokeRectWithWidth.
Call CGContextSetLineWidth, then CGContextAddRect (to add the rectangle to the current path), then CGContextDrawPath with kCGPathFillStroke. (Or call AddRect before SetLineWidth if you prefer—they only need to both happen before DrawPath.)
Note that a stroke is centered on the path outline, so half of it will be inside the path/rectangle and half of it will be outside. If your line is 1 pixel wide, this will appear as the line being halfway transparent (because there's no other way to represent “half a pixel”). If your line is some even number of pixels wide, and you stroke the entire bounds of the context (or view), you'll only see the half of the line that's inside.
You also should decide whether you really meant to fill at all, or whether stroke alone is what you wanted.
Related
I want to draw a circle on UIImageView. I have tried it but it didn't work.
This is a example image of what i want to achieve:
The circle should be drawn on where user taps on UIImageView and I want to do it without adding any sublayer.
Is it some way to do this?
so far i have used this code from the internet but it didn't worked.
- (UIImage *)imageByDrawingCircleOnImage:(UIImage *)image
pointX:(float) x
PointY:(float) y
{
// begin a graphics context of sufficient size
UIGraphicsBeginImageContext(image.size);
// draw original image into the context
[image drawAtPoint:CGPointZero];
// get the context for CoreGraphics
CGContextRef ctx = UIGraphicsGetCurrentContext();
// set stroking color and draw circle
[[UIColor redColor] setStroke];
// make circle rect 5 px from border
CGRect circleRect = CGRectMake(0, 0,
image.size.width,
image.size.height);
circleRect = CGRectInset(circleRect, x, y);
// draw circle
CGContextStrokeEllipseInRect(ctx, circleRect);
// make image out of bitmap context
UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();
// free the context
UIGraphicsEndImageContext();
return retImage;
}
Suppose your object's view is square, Set the cornerRadius to half of the width or height.
maskToBounds set your image as per shape of rounded imageView
For example,add this code for your requirement,
yourImageView.layer.cornerRadius = yourImageView.imageView.frame.size.height /2;
yourImageView.layer.masksToBounds = YES;
Hope this will help you :)
I have an origin vehicle image and what I need to implement is fill this with different colors:
http://image.openlan.ru/images/25842748100117640420.png
I've tried to reach it using code below:
- (UIImage *) coloredImageWithColor:(UIColor *)color
{
UIGraphicsBeginImageContext(self.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeDarken);
CGRect rect = (CGRect){ CGPointZero, self.size };
CGContextDrawImage(context, rect, self.CGImage);
CGContextClipToMask(context, rect, self.CGImage);
[color set];
CGContextFillRect(context, rect);
// wheel
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:(CGRect){ 700, 200, 200, 200 }];
CGContextSetBlendMode(context, kCGBlendModeClear);
[path fill];
UIImage *coloredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return coloredImage;
}
And of course it's not what I expected:
http://image.openlan.ru/images/05312201634158625573.png
Currently I've encountered with two problems. First of all I'd like to figure out how to reveal filled background in some area like wheels, as instance. And the second one is how to create the most similar colored vehicle images.
Your going to want to do most of this in Photoshop. You need a base image that is transparent in the places that you want to show through. Then you want to create a mask image that shows where you want color (using alpha to indicate how much tint to use). Then you'll mask the image and draw it on your background.
I assume a PhotoShop file with a layer mask was used to create the tinted vehicles in your initial example. You'll want those two layers (the base layer and the mask) as separate PNG files. Whoever created the original Photoshop file should be able to provide those.
Trying to do this programmatically from a single, flat image is unlikely to give you the kind of results you'd want.
I have looked at the various ways people are using to tint an image (I want to apply a red layer) and the only one I have go to work is ridiculously elaborate. Is there a simpler way?
// 1. Tint the Image
NSString *name = #"Skyline.png";
UIImage *imgBottomCrop = [UIImage imageNamed:name];
// begin a new image context, to draw our colored image onto
UIGraphicsBeginImageContext(imgBottomCrop.size);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
// set the fill color
[[UIColor redColor] setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, imgBottomCrop.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rectBottomCrop = CGRectMake(0, 0, img.size.width, img.size.height);
CGContextDrawImage(context, rectBottomCrop, imgBottomCrop.CGImage);
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextClipToMask(context, rectBottomCrop, imgBottomCrop.CGImage);
CGContextAddRect(context, rectBottomCrop);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Display Image
displayPicture2.image = coloredImg;
If the image is static (doesn't change while the application is running) the easiest way would be to have another image stored and just load it.
If it's not static - You're doing it correctly. Another way i can think of is just having a half-transparent red image stored and displaying it over Your image.
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.
I am drawing a circle using this code:
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(contextRef, 2.0);
CGContextSetStrokeColorWithColor(contextRef, [color CGColor]);
CGRect circlePoint = (CGRectMake(coordsFinal.x, coordsFinal.y, 50.0, 50.0));
CGContextStrokeEllipseInRect(contextRef, circlePoint);
The circle is added on my UIWindow, but I want it to be added in a UIImageView, maintaining the same coordinates as the UIWindow, so if the coordinates are outside the size of the UIImageView, the circle won't be seen. dimply draw the circle instead on the view, in the UIImageView.
You need to actually get an image from your canvas (context) and set that image on your imageview.
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();