Saving Image from UIImageView after manipulating Gestures - iphone

I'm trying to save the image after manipulating it with move, pinch and rotate gestoures.
All I get is the real image no matter what I tried,
I tried with UIGraphicsBeginImageContextWithOptions on the UIView container and on the UIIMageView without success.
Hope someone can help on this one.
Thanks,
Itay

You could try with this:
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
CGContextConcatCTM(UIGraphicsGetCurrentContext(), imageView.transform);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
This is assuming your imageView is transformed by means of a CGAffineTransform applied to it.

Related

How to draw a Mirrored UIImage in UIView with drawRect?

I load a image and create a mirror in this way:
originalImg = [UIImage imageNamed:#"ms06.png"];
mirrorImg = [UIImage imageWithCGImage:[originalImg CGImage] scale:1.0 orientation:UIImageOrientationUpMirrored];
Then I set the above UIImage object to a subclass of UIView, and override the drawRect:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGAffineTransform t0 = CGContextGetCTM(context);
CGContextConcatCTM(context, t0);
CGContextDrawImage(context, self.bounds, [image CGImage]);
CGContextRestoreGState(context);
}
No matter which image I draw, the displayed image always be the original one, mirrored image was never displayed when set to the UIView subclass.
I'm sure that the mirrored image was set to the UIView correctly because the debug info showed that the orientation member variable equals to 4, which means "UIImageOrientationUpMirrored", while the original image equals to 0.
Does anyone could help me with this problem, thanks.
I also tried to display the mirrored image in UIImageView with setImage: and it works correctly. By the way I found that the breakpoint in drawRect was never hit when call the setImage of UIImageView, how can we define the drawing behavior(such as draw a line above the image) when loading image to the UIImageView?
You mirrow the image on UI-Level. This returns a new UIImage, but the CGImage stays the same. If you do some NSLogs, you will notice this.
You can also do transformations on UI-Level. If you use this approach, I would suggest to use originalImg.scale instead of 1.0. Then the code would work for retina and non-retina displays.
[UIImage imageWithCGImage:[originalImg CGImage] scale:originalImg.scale orientation:UIImageOrientationUpMirrored];
If you really need to mirror the CGImage, take a look at NYXImagesKit on GitHub (see UIImage+Rotating.m)

Is there a way to create a UIImage without orientation?

I am about to crop images but facing the orientation issue while creating image using CGImageCreateWithImageInRect.
CGImageCreateWithImageInRect crops the image based on UIImage orientation so I cannot get the right images as I want.
I want the plain image from the UIImage/maybe-camera-image without orientation meta data.
Is there a way to achieve this?
EDIT:
I have the some selected rect of the 'UIImage'. If I apply the crop on the 'UIImage' it gives different output with some other orientation
Try this:
CGImageRef imageRef = CGImageCreateWithImageInRect(src.CGImage, croppingRect);
UIImage *result = [UIImage imageWithCGImage:imageRef scale:1.0f orientation:src.imageOrientation];
Could help someone!
-(UIImage*) removeImageOrientation:(UIImage*)ImgtakenByUser
{
UIGraphicsBeginImageContext(ImgtakenByUser.size);
[ImgtakenByUser drawInRect:CGRectMake(0, 0, ImgtakenByUser.size.width, ImgtakenByUser.size.height)];
UIImage *_image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return _image;
}
Thanks!

iphone sdk: UIScrollView as Image

I want to save the content of an UiScrollView as an Image. It seems that it is not as easy as the UIImageRepresentation that can be used for Views or ImageViews, anyone an idea how to do it?
I usually use a method implemented in a category:
+ (UIImage *)screenshot:(UIView *)view {
UIGraphicsBeginImageContext(view.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CALayer *layer = view.layer;
[layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
but, in your case, I suppose it will not suit well if your need is to get the whole content (also the part not visible in that moment). You could change the zoom value and then take the screenshot if it's a good enough solution.

Using CGContext to display a sprite sheet iPhone

So I have a spritesheet in png format, and have already worked out the coordinates for what I want to display. I'm trying to create a method that will return a UIImage when passed the location information on the spritesheet. I'm just not sure how to use the CGContext stuff along with the the coordinates to return an UIImage.
I was looking to CGContextClipToRect because I think that is the way to do it, but I just can't seem to get it to work.
Something like this
CGSize size = CGSizeMake(xSize, ySize);
UIGraphicsBeginImageContext(size);
//CGContextClipToRect(spriteSheet.size, imageRect);
[spriteSheet drawAtPoint:CGPointMake(xPos, yPos)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
returns only what is in the size Context. I need to be able to "move" this size window around the spritesheet if that makes sense.
Any help would be appreciated.
Thanks,
Mike
I think the call you want to use is CGImageCreateWithImageInRect
newImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect( [spriteSheet CGImage] , imageRect )];
you need to think of your co-ordinates backwards. The CGSize is fixed. Translate your xPos,yPos so that your sprite appears under the window.

Any quick and dirty anti-aliasing techniques for a rotated UIImageView?

I've got a UIImageView (full frame and rectangular) that i'm rotating with a CGAffineTransform. The UIImage of the UIImageView fills the entire frame. When the image is rotated and drawn the edges appear noticeably jagged. Is there anything I can do to make it look better? It's clearly not being anti-aliased with the background.
The edges of CoreAnimation layers aren't antialiased by default on iOS. However, there is a key that you can set in Info.plist that enables antialiasing of the edges: UIViewEdgeAntialiasing.
https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html
If you don't want the performance overhead of enabling this option, a work-around is to add a 1px transparent border around the edge of the image. This means that the 'edges' of the image are no longer on the edge, so don't need special treatment!
New API – iOS 6/7
Also works for iOS 6, as noted by #Chris, but wasn't made public until iOS 7.
Since iOS 7, CALayer has a new property allowsEdgeAntialiasing which does exactly what you want in this case, without incurring the overhead of enabling it for all views in your application! This is a property of CALayer, so to enable this for a UIView you use myView.layer.allowsEdgeAntialiasing = YES.
just add 1px transparent border to your image
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[image drawInRect:CGRectMake(1,1,image.size.width-2,image.size.height-2)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Remember to set the appropriate anti-alias options:
CGContextSetAllowsAntialiasing(theContext, true);
CGContextSetShouldAntialias(theContext, true);
just add "Renders with edge antialiasing" with YES in plist and it will work.
I would totally recommend the following library.
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
It contains lots of useful extensions to UIImage that solve this problem and also include code for generating thumbnails etc.
Enjoy!
The best way I've found to have smooth edges and a sharp image is to do this:
CGRect imageRect = CGRectMake(0, 0, self.photo.image.size.width, self.photo.image.size.height);
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, 0.0);
[self.photo.image drawInRect:CGRectMake(1, 1, self.photo.image.size.width - 2, self.photo.image.size.height - 2)];
self.photo.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Adding the Info.plist key like some people describe has a big hit on performance and if you use that then you're basically applying it to everything instead of just the one place you need it.
Also, don't just use UIGraphicsBeginImageContext(imageRect.size); otherwise the layer will be blurry. You have to use UIGraphicsBeginImageContextWithOptions like I've shown.
I found this solution from here, and it's perfect:
+ (UIImage *)renderImageFromView:(UIView *)view withRect:(CGRect)frame transparentInsets:(UIEdgeInsets)insets {
CGSize imageSizeWithBorder = CGSizeMake(frame.size.width + insets.left + insets.right, frame.size.height + insets.top + insets.bottom);
// Create a new context of the desired size to render the image
UIGraphicsBeginImageContextWithOptions(imageSizeWithBorder, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// Clip the context to the portion of the view we will draw
CGContextClipToRect(context, (CGRect){{insets.left, insets.top}, frame.size});
// Translate it, to the desired position
CGContextTranslateCTM(context, -frame.origin.x + insets.left, -frame.origin.y + insets.top);
// Render the view as image
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
// Fetch the image
UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
// Cleanup
UIGraphicsEndImageContext();
return renderedImage;
}
usage:
UIImage *image = [UIImage renderImageFromView:view withRect:view.bounds transparentInsets:UIEdgeInsetsZero];