UIView screenshot with magnificationFilter - ios

I have a tiny qrcode UIImage set to a large UIImageView. In order to avoid any gradient from black to white when amplifying, I setted the UIImageView magnification filter to kCAFilterNearest as shown below (it works):
[QRCodeImageView layer].magnificationFilter = kCAFilterNearest;
Now I need to take a screenshot from this ImageView, but the result image is ignoring the magnification filter:
Here is my screenshot code:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(QRCodeImageView.frame.size.width, QRCodeImageView.frame.size.height),YES, 2.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[QRCodeImageView.layer renderInContext:context];
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
So, the question is, how to render in context with a given magnification filter?
Thanks in advance

Related

UIImage with alpha produces White Image

I have below block of code to apply alpha on UIImage,
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:alpha];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Following is the original Image before alpha being applied:
But after applying alpha with the above mentioned code it resulted in the following image(alpha applied with value 0.6):
I supposed to receive a transparent image instead image is getting whitened as i keep apply alpha, If i apply an alpha of 0.0 the resulted image was a pure white image, any suggestions would be appreciated.

How to save UIView content (screenshot) without reducing it's quality

I have a UIView and I want to save it's content to an image, I successfully did that using UIGraphicsBeginImageContext and UIGraphicsGetImageFromCurrentImageContext() but the problem is that the image quality is reduced. Is there a way to take a screenshot/save UIView content to an image without reducing it's quality?
Here's a snippet of my code:
UIGraphicsBeginImageContext(self.myView.frame.size);
[self.myview.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Try Following Code :
UIGraphicsBeginImageContextWithOptions(YourView.bounds.size, NO, 0);
[YourView drawViewHierarchyInRect:YourView.bounds afterScreenUpdates:YES];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
This code working Awsome...!!!
Mital Solanki’s answer is a fine solution, but the root of the problem is that your view is on a retina screen (so has a scale factor of 2) and you are creating a graphics context with a scale factor of 1. The documentation for UIGraphicsBeginImageContext states:
This function is equivalent to calling the UIGraphicsBeginImageContextWithOptions function with the opaque parameter set to NO and a scale factor of 1.0.
Instead use UIGraphicsBeginImageContextWithOptions with a scale of 0, which is equivalent to passing a scale of [[UIScreen mainScreen] scale].

Drawing a circular image on top of another image - UIGraphicsBeginImageContextWithOptions

I've been struggling with this method for a while. I am drawing an avatar on top of another image. The user picture I want to be a circle, however I can't seem to figure out how. The user picture is a UIImage and not a UIImageView. I am aware of how to make a circle if it is an imageview. Below is the code. There might be a better approach.
-(UIImage *)drawImage:(UIImage*)pinImage withBadge:(UIImage *)user{
UIGraphicsBeginImageContextWithOptions(pinImage.size, NO, 0.0f);
[pinImage drawInRect:CGRectMake(0, 0, pinImage.size.width, pinImage.size.height)];
[user drawInRect:CGRectMake(20.0, 10.0, user.size.width/2, user.size.height/2)];
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultImage;
}
The result is good, but the user image is still square, it is not circle. I have tried making the add the User image to a UIImageView, transform it to a circle, and then use it in the method by calling yourImageView.image, but no luck. I also tried numerous other ways. My logic is more than likely incorrect.
The desired outcome is a rounded image place on top of a pin/annotation. Where the black dot would be an image (a bigger circle than this).
You can clip the image context to the path of an image
// Start the image context
UIGraphicsBeginImageContextWithOptions(pinImage.size, NO, 0.0);
UIImage *resultImage = nil;
// Get the graphics context
CGContextRef context = UIGraphicsGetCurrentContext();
// Draw the first image
[pinImage drawInRect:CGRectMake(0, 0, pinImage.size.width, pinImage.size.height)];
// Get the frame of the second image
CGRect rect = CGRectMake(20.0, 10.0, user.size.width/2, user.size.height/2)
// Add the path of an ellipse to the context
// If the rect is a square the shape will be a circle
CGContextAddEllipseInRect(context, rect);
// Clip the context to that path
CGContextClip(context);
// Do the second image which will be clipped to that circle
[user drawInRect:rect];
// Get the result
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
// End the image context
UIGraphicsEndImageContext();
Create a circular path and then clip to that?
CGContextAddArc(ctx, ....);
CGContextClip(ctx);

Ios taking snapshot of a screen after cropping some parts

Yep as the title says I need to take a cropped snapshot of my app.
I want to cut top of the screenshot little bit (%20) I already have a code which I used to take a snapshot and send it to facebook and its working but its taking the photo of all of the screen so how can tell my code to ignore the %20 percent of the screen.Maybe with height and width also I looked some questions in the stack overflow and manage to slide my screenshot so I get rid of the unwanted part at the top but this time at the bottom huge white area appeared so it didnt solve my problem.
Here is my snapshot code
UIGraphicsBeginImageContext(self.ekran.bounds.size);
[self.ekran.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
A method to crop the image, that accepts any frame to crop the image against
- (UIImage *)cropImage:(UIImage *)imageToCrop toRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
Use it as follows:
UIGraphicsBeginImageContext(self.ekran.bounds.size);
[self.ekran.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGFloat imgHight = resultingImage.size.height;
// Create a frame that crops the top 20% of the image
CGRect* imageFrame = CGRectMake(0, imgHight - (imgHight*0.8), width, imgHight*0.8);
resultingImage = [self cropImage:resultingImage toRect:imageFrame];

Cropping ellipse using core image in ios

I want to crop an ellipse from an image in ios. Using core image framework, I know know to crop a reactangular region.
Using core graphics, I am able to clip the elliptical region. But, the size of the cropped image is same as the size of the original image as I am applying mask to area outside the ellipse.
So, the goal is to crop the elliptical region from an image and size of cropped image won't exceed the rectangular bounds of that image.
Any help would be greatly appreciated. Thanks in advance.
You have to create a context in the correct size, try the following code:
- (UIImage *)cropImage:(UIImage *)input inElipse:(CGRect)rect {
CGRect drawArea = CGRectMake(-rect.origin.x, -rect.origin.y, input.size.width, input.size.height);
UIGraphicsBeginImageContext(rect.size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, rect.size.width, rect.size.height));
CGContextClip(ctx);
[input drawInRect:drawArea];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Maybe you have to adjust the drawArea to your needs as i did not test it.

Resources