How to capture UIView as UIImage in particular frame? - objective-c

Hi i want to covert my UIView to UIImage in particular frame size kindly help me.
I have 'UITableView` which is added as subview of 'UIScrollView' for horizontal scroll, my table view frame size is (0, 0, 12000, 768).
I want to convert the current visible are of my UITableView as UIImage after scrolling.
Example:
if i scrolled my table view horizontally some distance means that current visible are is (150,0,1200,768) that means full device screen.
if i use the following code:
UIGraphicsBeginImageContext(self.frame.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
its capturing always the frame size of (0, 0, 1200, 768) only.
so, how can i set the origin of image capturing.
Kindly help me out.... Thanks in advance....

- (UIImage *)rasterizedImageInView:(UIView *)view atRect:(CGRect)rect {
UIGraphicsBeginImageContextWithOptions(rect.size, view.opaque, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);
[view.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
This will allow you to capture a UIImage from a particular region within a UIView as defined by a CGRect.

CGRect rect = [self.view bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Try this.
UIView *viewprint=[[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
viewprint.backgroundColor=[UIColor whiteColor];
tableView.frame = CGRectMake(0, 0, width, height);
[viewprint addSubview:tableView];
UIGraphicsBeginImageContext(viewprint.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Related

The rounded pure color image created by code is blur

In objective-c, I make a circle shape programmatically by following codes:
+(UIImage *)makeRoundedImage:(CGSize) size backgroundColor:(UIColor *) backgroundColor cornerRadius:(int) cornerRadius
{
UIImage* bgImage = [self imageWithColor:backgroundColor andSize:size];;
CALayer *imageLayer = [CALayer layer];
imageLayer.frame = CGRectMake(0, 0, size.width, size.height);
imageLayer.contents = (id) bgImage.CGImage;
imageLayer.masksToBounds = YES;
imageLayer.cornerRadius = cornerRadius;
UIGraphicsBeginImageContext(bgImage.size);
[imageLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return roundedImage;
}
The imageWithColor method is as following:
+(UIImage *)imageWithColor:(UIColor *)color andSize:(CGSize)size
{
//quick fix, or pop up CG invalid context 0x0 bug
if(size.width == 0) size.width = 1;
if(size.height == 0) size.height = 1;
//---quick fix
UIImage *img = nil;
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context,
color.CGColor);
CGContextFillRect(context, rect);
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Then I used it to create a pure color circle shape image, but what I found is the circle image is not perfect rounded. As an example, please see following code:
CGSize size = CGSizeMake(diameter, diameter);
int r = ceil((float)diameter/2.0);
UIImage *imageNormal = [self makeRoundedImage:size backgroundColor:backgroundColor cornerRadius:r];
[slider setThumbImage:imageNormal forState:UIControlStateNormal];
First I created a circle image, then I set the image as the thumb to a UISlider. But what shown is as the picture shown below:
You can see the circle is not an exact circle. I'm thinking probably it caused by the screen resolution issue? Because if I use an image resource for the thumb, I need add #2x. Anybody know the reason? Thanx in advance.
updated on 8th Aug 2015.
Further to this question and the answer from #Noah Witherspoon, I found the blurry edge issue has been solved. But still, the circle looks like being cut. I used the code as following:
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;
And the circle looks like:
You can see the edge has been cut.
I changed 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;
You can see the circle looks better(The top edge and the bottom edge):
I made the fill rect size smaller, and the edge looks better, but I don't think it's a nice solution. Still, does anybody know why this happen?
From your screenshot it looks like you do actually have a circular image, but its scale is wrong—it’s not Retina—so it looks blurry and not-circular. The key thing is that instead of using UIGraphicsBeginImageContext which defaults to a scale of 1.0 (as compared to your screen, which is at a scale of 2.0 or 3.0), you should be using UIGraphicsBeginImageContextWithOptions. Also, you don’t need to make a layer or a view to draw a circle in an image context.
+ (UIImage *)makeCircleImageWithDiameter:(CGFloat)diameter color:(UIColor *)color {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(diameter, diameter), NO, 0 /* scale (0 means “use the current screen’s scale”) */);
[color setFill];
CGContextFillEllipseInRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, diameter, diameter));
UIImage *image = UIGraphicsGetImageFromCurrentContext();
UIGraphicsEndImageContext();
return image;
}
If you want to get a circle every time try this:
- (UIImage *)makeCircularImage:(CGSize)size backgroundColor:(UIColor *)backgroundColor {
CGSize squareSize = CGSizeMake((size.width > size.height) ? size.width : size.height,
(size.width > size.height) ? size.width : size.height);
UIView *circleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, squareSize.width, squareSize.height)];
circleView.layer.cornerRadius = circleView.frame.size.height * 0.5f;
circleView.backgroundColor = backgroundColor;
circleView.opaque = NO;
UIGraphicsBeginImageContextWithOptions(circleView.bounds.size, circleView.opaque, 0.0);
[circleView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}

How to capture a specific size of the self.view

I have the self.view, but I only want to capture 300x320 of it.
got this code:
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
UIImage * imgPrintScreen = [[UIImage alloc]init];
imgPrintScreen = viewImage;
What do I need to change here in order to do so?
Thanks allot!
Just change the size that you want to capture, instead of using the entire bounds, use the size you want. The render will start at the origin of the view and be clipped when it falls outside the bounds. If you need to change where the view is actually clipped, simply translate the context after starting the image context:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 320), YES, 0.);
[self.view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
If your view was, for example, 600x320 and you wanted to capture the middle 300 points in width, you'd translate the context 150 points to the left:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 320), YES, 0.);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, -150.f, 0.f);
[self.view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Prevent UIImage from resizing when - drawInRect: is called

I'm rendering UIImage in the - drawRect: and placing it in the passed in CGRect by calling drawInRect: rect on the UIImage. It automatically resizes and stretches itself, which I don't want. How can I keep it the original size?
UIImage* left = [UIImage imageNamed: #"Map_info_bubble_left"];
UIImage* center = [UIImage imageNamed: #"Map_info_bubble_center"];
UIImage* right = [UIImage imageNamed: #"Map_info_bubble_right"];
UIImage* leftCapStretched = [left resizableImageWithCapInsets: UIEdgeInsetsMake(0, 20, 0, 0)];
UIImage* rightCapStretched = [right resizableImageWithCapInsets: UIEdgeInsetsMake(0, 0, 0, 15)];
CGFloat fullWidth = leftCapStretched.size.width + center.size.width + rightCapStretched.size.width;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(fullWidth, center.size.height), NO, 0);
[leftCapStretched drawAtPoint: CGPointMake(0, 0)];
[center drawAtPoint: CGPointMake(leftCapStretched.size.width, 0)];
[rightCapStretched drawAtPoint: CGPointMake(left.size.width + center.size.width, 0)];
UIImage* callout = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[callout drawInRect: rect];
Essentially what is happening is the center image should remain the original size while the caps stretch, but the center is stretching and the caps don't stretch enough. I noticed that if I multiply fullWidth by 2, it shrinks the center closer to what it should be.
EDIT: More simply asked after reading the documentation a bit more, is there a way to prevent the UIImage from scaling to fit the rect when drawInRect: is called?
This can be done simply by passing the images size property to drawInRect:
e.x:
[myImage drawInRect:CGRectMake(someOriginX, someOriginY, myImage.size.width, myImage.size.height)];

objective-c - Create an UIImage with Core Graphics

I have this code and it's not adding anything to the view, can you help me figure out what is wrong?
also I will apply a filer to image, but that will be later, when I get this done, but tell me if this is a wrong approach if Im going to add filters.
UIGraphicsPushContext(context);
CALayer *layer = [CALayer layer];
CGColorRef bgColor = [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor;
layer.frame = CGRectMake(0, 0, 200, 200);
CGContextSetFillColorWithColor(context, bgColor);
CGContextFillRect(context, layer.bounds);
CGContextSaveGState(context);
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
CGContextSetFillColorSpace(context, patternSpace);
CGColorSpaceRelease(patternSpace);
CGContextFillRect(context, layer.bounds);
CGContextRestoreGState(context);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *borrar = [[UIImageView alloc]initWithImage:image];
[self.view addSubview:borrar];
You never open an image context. Use UIGraphicsBeginImageContextWithOptions.

Image from UIView

is there any Possibility to create a image out of a UIView?
Thanks,
Andreas
#import "QuartzCore/QuartzCore.h" after you added the framework to your project. Then do:
UIGraphicsBeginImageContext(yourView.frame.size);
[[yourView layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// The result is *screenshot
I have used the answer to improve it even further. Unfortunately, the original code only produced a mirrored image.
So here's the working code:
- (UIImage *) imageFromView:(UIView *)view {
UIGraphicsBeginImageContext(view.frame.size);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(currentContext, 0, view.size.height);
// passing negative values to flip the image
CGContextScaleCTM(currentContext, 1.0, -1.0);
[[appDelegate.scatterPlotView layer] renderInContext:currentContext];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenshot;
}