UIGraphicsGetImageFromCurrentImageContext change image size - ios

I am making drawing application where i need to draw image.
But when i try to to that image size is change. i want the same size of image after draw.
Here is my code
NSLog(#"%#",NSStringFromCGSize(self.image.size));
self.image = UIGraphicsGetImageFromCurrentImageContext();
NSLog(#"%#",NSStringFromCGSize(self.image.size));
O/p
2014-08-24 15:11:14.511 Demo[4877:60b] {877, 1136}
2014-08-24 15:11:15.533 Demo[4877:60b] {320, 460}
How can take image quality same as before Here image is scale down

//UIGraphicsBeginImageContext(imageView.frame.size)
//Use this:
let hasAlpha = true
let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
let size = (size of your canvas / imageview)
UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale) //use this
//Instead of this:
UIGraphicsBeginImageContext(imageView.frame.size) //dont use this

Related

UIImage size doubled when converted to CGImage?

I am trying to crop part of an image taken with the iPhone's camera via the cropping(to:) method on a CGImage but I am encountering a weird phenomenon where my UIImage's dimensions are doubled when converted with .cgImage which, obviously, prevents me from doing what I want.
The flow is:
Picture is taken with the camera and goes into a full-screen imageContainerView
A "screenshot" of this imageContainerView is made with a UIView extension, effectively resizing the image to the container's dimensions
imageContainerView's .image is set to now be the "screenshot"
let croppedImage = imageContainerView.renderToImage()
imageContainerView.image = croppedImage
print(imageContainerView.image!.size) //yields (320.0, 568.0)
print(imageContainerView.image!.cgImage!.width, imageContainerView.image!.cgImage!.height) //yields (640, 1136) ??
extension UIView {
func renderToImage(afterScreenUpdates: Bool = false) -> UIImage {
let rendererFormat = UIGraphicsImageRendererFormat.default()
rendererFormat.opaque = isOpaque
let renderer = UIGraphicsImageRenderer(size: bounds.size, format: rendererFormat)
let snapshotImage = renderer.image { _ in
drawHierarchy(in: bounds, afterScreenUpdates: afterScreenUpdates)
}
return snapshotImage
}
}
I have been wandering around here with no success so far and would gladly appreciate a pointer or a suggestion on how/why the image size is suddenly doubled.
Thanks in advance.
This is because print(imageContainerView.image!.size) prints the size of the image object in points and print(imageContainerView.image!.cgImage!.width, imageContainerView.image!.cgImage!.height) print the size of the actual image in pixels.
On iPhone you are using there are 2 pixels for evert point in both horizontal and vertical. The UIImage scale property will give you the factor which in your case will be 2.
See this link iPhone Resolutions

Scale an Image in ImageView (Scale x,y) - IOS

I usually scale the image of an imageView in Android with the scaleX and scaleY properties.
How can I do the same in IOS? I'm really new with IOS,I'm using swift 3 and I didn't find any analog thing like that.
If you need to scale the image proportionally, the following code might work for you:
if let cgImage = imageView.image?.cgImage, let orientation = imageView.image?.imageOrientation {
imageView.image = UIImage(cgImage: cgImage, scale: newScale, orientation: orientation)
}
However, if you only want to display it with a size different than that of the original image, you should control the size of the image using the size of the UIImageView that presents it. To make sure the image scales correctly with the size of the view, take a look at the UIImageView.contentMode property: https://developer.apple.com/reference/uikit/uiview/1622619-contentmode

How to get image without resizing?

first of all i need to describe what i gonna to do:
i need to display a header image with full screen width for all devices.
there for i should provide multiple pictures with different sizes, and not just 2x and 3x.
so i would have these images:
header_width_1242.png for iphone 6 plus.
header_width_1125.png for iphone 6 plus display zoom
header_width_640.png for iphone 5,6
...
so i shouldn't choose image according to the scale, rather i should choose image according to the width:
let image_name = "header_width_" + String(UIScreen.mainScreen().scale * UIScreen.mainScreen().bounds.width)
let image = UIImage(named:image_name)
the problem, that ios scale the image automatically again. so if the device with scale 2x. then it return the image * 2 size.
e.g : for iphone 5 which has width 320 and scale 2, i need the header_width_640.png , but it seems that the system scale the image to 1280 (640 * 2).
How could i tell the system, to return image UIImage(named:image_name) without scaling ?thanks
You could declare a screenSize property on your viewController.
// Determine screen size
let screenSize: CGRect = UIScreen.mainScreen().bounds
Then, when you need to set an image, you could do the following:
if screenSize.width < 641 {
// set your imageView to the image for 640 screen width
} else if screenSize.width < 1126 {
// set your imageView to the image for 1125 screen width
} else if screenSize.width < 1243 {
// set your imageView to the image for 1242 screen width
}
You should not constraint assets by screen size, is better if you do by using size classes if available. Image assets directory make this possible in the inspector panel, by choosing the size classes for each image.
I do understand that sometimes is a need, but try to think in a relative perspective. If the image is something like a logo aligned by left or right you can use slicing to create stretchable end/beginning on the image.
If the image is center with a solid color or something drawable by code you can draw it at run time.
Here is a snippet in ObjC that use in an app of mine you can easily convert in SWIFT:
-(UIImage*) createNavBarBackgroundWithImage:(UIImage*) image {
CGSize screenSize = ((CGRect)[[UIScreen mainScreen] bounds]).size;
CGFloat width = screenSize.width;
CGFloat height = 64.0;
UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), NO, 0.0);
//Draw background
UIColor * backGroundColor = [UIColor colorWithRed:27.f/255.f green:142.f/255.f blue:138.f/255.f alpha:1.0];
[backGroundColor setFill];
UIRectFill(CGRectMake(0, 0, width, height));
//Draw the image at the center
CGPoint point = CGPointMake(width/2 - image.size.width/2, 0);
[image drawAtPoint:point];;
UIImage *newBGImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newBGImage;
}
Use Image Asset
https://developer.apple.com/library/ios/recipes/xcode_help-image_catalog-1.0/chapters/AddingImageSets.html
header_width_1242.png for iphone 6 plus. Name it header_width_414.png drag to 3x
header_width_1125.png name it header_width_375.png drag to 3x
header_width_640.png name it header_width_320.png drag to 2x
let image_name = "header_width_" + UIScreen.mainScreen().bounds.width)
let image = UIImage(named:image_name)

Downscaled image is drawn in very low quality?

I have a big logo image (1000x500). I want to use this image and draw it in a frame of size 100x100. Here is how I do it:
self.logo = UIImageView(image: UIImage(named: "logoBig")!)
self.logo?.contentMode = UIViewContentMode.ScaleAspectFit
self.logo?.frame = CGRectMake(self.view.bounds.width/2 - 50, 50, 100, 100)
self.view.addSubview(self.logo!)
This works. The problem is that the image quality is very low after the reduction of the image size.
How can I draw my big image into a smaller frame without loosing quality?
Try like this:
let logo = UIImageView(frame: CGRectMake(view.bounds.midX - 50, 50, 100, 100))
logo.contentMode = .ScaleAspectFit
logo.image = UIImage(named: "logoBig")!
view.addSubview(logo)
try using this method
- (UIImage*)resizeImage:(UIImage*)image scaledToSize:(CGSize)newSize{
//UIGraphicsBeginImageContext(newSize);
// In next line, pass 0.0 to use the current device's pixel scaling factor (and thus account for Retina resolution).
// Pass 1.0 to force exact pixel size.
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
and if you want to resize the image again, keep the original image and use it for different sizes.
ADD NOTES:
Also, the original image size of 1000x500, resizing it would loose the image's aspect ratio because 100x100 is not propotional to the original image size.

Take Screenshot of Textfield in swift?

Am making an iOS application which captures screenshot of a textview filled with some image. The problem is that the screen shot captures the entire screen.
How do I take screen shot of UITextView using Swift?
The following worked for me
UIGraphicsBeginImageContextWithOptions(self.textField.bounds.size, false, 0);
self.textField.drawViewHierarchyInRect(self.textField.bounds, afterScreenUpdates: true)
let copied = UIGraphicsGetImageFromCurrentImageContext();
imageView.image = copied
UIGraphicsEndImageContext();
You can save any view as image by using drawViewHierarchyInRect method
UIGraphicsBeginImageContextWithOptions(self.textView.bounds.size, false, 0);
self.textText.drawViewHierarchyInRect(CGRectMake(0, 0, self.textView.frame.size.width, self.textView.frame.size.height),afterScreenUpdates:true)
var screenShot:UIImage = UIGraphicsGetImageFromCurrentImageContext();
All answers are good but missing is scale which is necessary in context.
Use UIView's drawViewHierarchyInRect mehtod to capture screen.
//Use screen scale for better images
let screenScale = UIScreen.mainScreen().scale;
//create context
UIGraphicsBeginImageContextWithOptions(yourView.bounds.size, false, screenScale);
//use view for drawing
yourView.drawViewHierarchyInRect(yourView.bounds, afterScreenUpdates: true)
//get captured image
let capturedImage = UIGraphicsGetImageFromCurrentImageContext();
//last dump context
UIGraphicsEndImageContext();
Another sloution : use UIView's layer's renderInContext
//Use screen scale for better images
let screenScale = UIScreen.mainScreen().scale;
//create context
UIGraphicsBeginImageContextWithOptions(yourView.bounds.size, false, screenScale);
//use view for drawing
yourView.layer.renderInContext(UIGraphicsGetCurrentContext())
//get captured image
let capturedImage = UIGraphicsGetImageFromCurrentImageContext();
//last dump context
UIGraphicsEndImageContext();

Resources