Draw bezier curve above image of UIImageView - objective-c

How to draw beziercurve above the image of the UIImageView. I am subclassing UIImageView and drawing circles using UIBezierCurve on the corners of image view. But as soon as i place the image in UIImageView the inside part of circles are overlapped by the image. So is there any solution which lets me draw the UIBezier path on the UIimage of uiimageview ?

You can try subclassing simple UIView and drawing an image yourself using drawInRect: method of UIImage instance. It should look something like this:
- (void)drawRect:(CGRect)dirtyRect {
// note you can get image from anywhere
UIImage *image = [UIImage imageNamed:#"MyImage"];
[image drawInRect:self.bounds];
// now that image is drawn, everything
// past this point will be drawn on top of it
...
}

Related

Get Image from image View

if we add more than one View to imageView and NSString also. Is it possible to get image from ImageView that contain all images and strings etc?
like this
From what I understand in your question, you have added an ImageView for the building, another for the video symbol (as a subview) and a UILabel (again as a subview) for the time. You want all these to be rendered as a single UIImage. For this, you can use:
UIGraphicsBeginImageContext(imageView.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[imageView.layer renderInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The screenshot UIImage will contain your desired image.

Get UIImage from UIImageView with masked subviews

Through Face Detection, I want to blur eyes and mouth of a person. So I have a imageView that contains 3 subviews (2 per eye and the mouth). Each one of these subviews were masked with a PNG shape (with background clear) for avoiding to show rectangle.
My imageView in screen remain so: http://screencast.com/t/ak4SkNXM0I
And I want to obtain the image for storing in another place, so I've tried this:
CGSize size = [imageView bounds].size;
UIGraphicsBeginImageContext(size);
[[imageView layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
But finalImage is an image like this:
http://screencast.com/t/eDlvGqqY
My subViews (eyes and mouth) are not masked as above.
Any idea?
Thanks.
Edit:
I have to use library compatible with ios6
You can check the new API added to iOS7. Try one of the following methods:
snapshotViewAfterScreenUpdates:
resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets: for resizable image
drawViewHierarchyInRect:afterScreenUpdates:

Using cornerRadius on a UIImageView in a UITableViewCell

I'm using a UIImageView for each of my UITableViewCells, as thumbnails. My code uses SDWebImage to asynchronously grab those images from my backend and load them in, and then caching them. This is working fine.
My UIImageView is a 50x50 square, created in Interface Builder. Its background is opaque, white color (same as my UITableViewCell background color, for performance). However, I'd like to use smooth corners for better aesthetics. If I do this:
UIImageView *itemImageView = (UIImageView *)[cell viewWithTag:100];
itemImageView.layer.cornerRadius = 2.5f;
itemImageView.layer.masksToBounds = NO;
itemImageView.clipsToBounds = YES;
My tableview drops around 5-6 frames immediately, capping about 56 FPS during fast scrolling (which is okay), but when I drag and pull the refresh control, it lags a bit and drops to around 40 FPS. If I remove the cornerRadius line, all is fine and no lag. This has been tested on an iPod touch 5G using Instruments.
Is there any other way I could have a rounded UIImageView for my cells and not suffer a performance hit? I'd already optimized my cellForRowAtIndexPath and I get 56-59 FPS while fast scrolling with no cornerRadius.
Yes, that's because cornerRadius and clipToBounds requires offscreen rendering, I suggest you to read these answer from one of my question. I also quote two WWDC session thatyou should see. The best thing you can do is grab the image right after is downloaded and on another thread dispatch a method that round the images. Is preferable that you work on the image instead of the imageview.
// Get your image somehow
UIImage *image = [UIImage imageNamed:#"image.jpg"];
// Begin a new image that will be the new image with the rounded corners
// (here with the size of an UIImageView)
UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0);
// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:imageView.bounds
cornerRadius:10.0] addClip];
// Draw your image
[image drawInRect:imageView.bounds];
// Get the image, here setting the UIImageView image
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
// Lets forget about that we were drawing
UIGraphicsEndImageContext();
Method grabbed here
You can also subclass the tableviewcell and override the drawRect method.
The dirty but very effective way is draw a mask in photoshop with inside alpha and around the matching color of the background of the cell and add another imageView, not opaque with clear background color, on the one with images.
There is another good solution for this. I did it a few times in my projects. If you want to create a rounded corners or something else you could just use a cover image in front of your main image.
For example, you want to make rounded corners. In this case you need a square image layer with a cut out circle in the center.
By using this method you will get 60fps on scrolling inside UITableView or UICollectionView. Because this method not required offscreen rendering for customizing UIImageView's (like avatars and etc.).
Non blocking solution
As a follow up to Andrea's response, here is a function that will run his code in the background.
+ (void)roundedImage:(UIImage *)image
completion:(void (^)(UIImage *image))completion {
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Begin a new image that will be the new image with the rounded corners
// (here with the size of an UIImageView)
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
CGRect rect = CGRectMake(0, 0, image.size.width,image.size.height);
// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:rect
cornerRadius:image.size.width/2] addClip];
// Draw your image
[image drawInRect:rect];
// Get the image, here setting the UIImageView image
UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
// Lets forget about that we were drawing
UIGraphicsEndImageContext();
dispatch_async( dispatch_get_main_queue(), ^{
if (completion) {
completion(roundedImage);
}
});
});
}
Swift 3 version of thedeveloper3124's answer
func roundedImage(image: UIImage, completion: #escaping ((UIImage?)->(Void))) {
DispatchQueue.global().async {
// Begin a new image that will be the new image with the rounded corners
// (here with the size of an UIImageView)
UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
let rect = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
// Add a clip before drawing anything, in the shape of an rounded rect
UIBezierPath(roundedRect: rect, cornerRadius: image.size.width/2).addClip()
// Draw your image
image.draw(in: rect)
// Get the image, here setting the UIImageView image
guard let roundedImage = UIGraphicsGetImageFromCurrentImageContext() else {
print("UIGraphicsGetImageFromCurrentImageContext failed")
completion(nil)
return
}
// Lets forget about that we were drawing
UIGraphicsEndImageContext()
DispatchQueue.main.async {
completion(roundedImage)
}
}
}

Show portion of UIImage in UIImageVIew

This question might have been answered, but I can't find a solution to my problem after hours of googling.
I have a UIImageView (320*320) in a custom UITableCell with a UIImage (320*320) inside.
When I click on a button, the UIImageView resizes to 320*80 (animated) and the UIImage too.
How could I do to prevent the UIImage from resizing ?
I would like this UIImage to stay but same and show only a portion of this image ( a 320*80 frame with 0/0 origin)
Edit : Cropping
I thought of cropping the image to the right size and then set the UIImageView's image to the fullsize image, but it looks ugly because when the user clicks on the UIImageView, this one is still 320*320 but the UIImage has been set to the cropped one (320*80) so it is streched...
Thanks
I'm doing something similar in one of my apps, when I create the UIImageView object, I set the property contentMode to UIViewContentModeScaleAspectFill, and the clipsToBounds property to YES. Hope this helps.
You can resize the image and then replace the UIImageView image with the resized one.
CGImageRef imageToBeResized = yourImage.CGImage;
CGImageRef partOfImageAsCG = CGImageCreateWithImageInRect(imageToBeResized, CGRectMake(0, 0, 320, 80));
CGRelease(imageToBeResized);
UIImage *resizedImage = [UIImage imageWithCGImage:imageToBeResized];
Maybe you should think about use a UIScrollView with your UIImageView inside. So, you can with its properties to archive the desired behaviour.

Custom drawing on top of UIButton's background image

What is the method calling sequence of UIButton's drawing?
I have a UIButton subclass, let's call it UIMyButton. I add it to a .xib controller and give it a background image. Then in the UIMyButton.m file I override drawRect method and draw a shape.
Something like:
- (void)drawRect:(CGRect)rect {
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(c, [UIColor orangeColor].CGColor);
CGContextFillRect(c, rect);
}
The problem is that it draws the orange rectangle underneath the background image. What methods are responsible for drawing/updating background images (it updates on "tap down" for example)? How do I force the draw on top without adding an additional custom subview to the button (or is the background image a subview itself)?
I'm just trying to get a clear understanding of how the UIButton drawing sequence works.
The solution is to not use a background for the button. Instead, draw the image inside the drawRect method like so:
-(void)drawRect:(CGRect)rect
{
CGContextRef ctx=UIGraphicsGetCurrentContext();
UIImage *image = [UIImage imageNamed:#"image.jpg"];
[image drawInRect:self.bounds];
CGContextSetFillColorWithColor(c, [UIColor orangeColor].CGColor);
CGContextFillRect(c, rect);
}