Drawing a UILabel with Transformations - ios

I have a UILabel (but this should apply to any UIView). I am trying to draw a label to a UIImage.
First, I've applied a transformation to a label:
let label = UILabel(frame: CGRectMake(0,0,100,100))
label.text = "Fizz Buzz"
label.transform = CGAffineTransformRotate(label.transform, 5)
label.transform = CGAffineTransformScale(label.transform, 2, 2)
label.setTranslation(CGPointMake(10, 15), inView: view)
Then, I want to draw the label to an Image.
UIGraphicsBeginImageContextWithOptions(view.frame.size, false, 0)
let context = UIGraphicsGetCurrentContext()
label.drawTextInRect(view.frame)
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Now, the result UIImage that appears is an image of the label with the proper text, but without a the transformation. How do I ensure that the view draws with the transforms?

You need to get the current UIImage data not just the frame to be able to add text to that image. I have a simple function below that adds text to an image. If you are using a UIImageView , you can get the currently assigned image to it, passed it to the function and set the image returned by the function to that UIImageView.
extension UILabel
{
func getRenderedImage() -> UIImage
{
UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0)
var context = UIGraphicsGetCurrentContext()
CGContextSaveGState(context)
self.layer.renderInContext(context!)
let renderedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return renderedImage
}
}
Sample Usage:
let newImage = label.getRenderedImage()
imagView.image = newImage

To start a small change should be made in the 3rd line of the second code snippet. Replace label.drawTextInRect(view.frame) with label.drawTextInRect(label.frame).
However to properly maintain the transformations, I discovered the easiest way was to create a wrapper UIView. Still apply the transformations to the label, but draw the wrapper view to a UIImage instead of the label. Use the line:
wrapperView.drawViewHierarchyInRect(wrapperView.frame, afterScreenUpdates: true)

Related

Image isn't bound to the UIImageView

I have a UIImageView in created in Inspector that I resize in my code based on a selected image which i get from the web. However on first load of the image, it's being displayed in the images normal resolution instead of the UIImageViews newly created bounds.
Resizing the UIImageView:
fullScreenImage.bounds.size = CGSize(width: scaledWidth, height: scaledHeight)
Setting the UIImageView's image
let imageStringURL = images[indexPath.row].urls!["regular"]
let imageURL = URL(string: imageStringURL!)!
let imageData = try! Data(contentsOf: imageURL)
let image = UIImage(data: imageData)
fullScreenImage.image = image
This is how it looks when the image is first clicked on to enter "fullscreen mode"
This is how it looks the second time i click it
Not really sure why the Image isn't bounding itself within the specified UIImageView bounds
Instead of resizing the bound, you can set the UIViewContentMode property of UIImageView. This will resize the imageView image to fit inside the bounds.
fullScreenImage.contentMode = .scaleAspectFit
I found a workaround solution. I tried setting the contentMode to aspect fit, and i also tried enabling clip to bounds in the inspector, however none of them worked. So I simply looked into just resizing the UIImage itself and placing it into the UIImageView.
I found an extension in another post for a UIImage that resizes it
extension UIImage{
func resizeImage(newSize: CGSize) -> UIImage {
// Guard newSize is different
guard self.size != newSize else { return self }
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0);
self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
}
If anyone knows of a better way please let me know :)

ios swift create rounded profile image like twitter, instagram,

I would like to create a very simple image editor, same as twitter (for the profile image)
I know how to pinch or move an image.
But i don’t know how to create the "circle layer" and just keep this part of the image, like this :
Make sure to import QuarzCore.
func maskRoundedImage(image: UIImage, radius: CGFloat) -> UIImage {
let imgView: UIImageView = UIImageView(image: image)
let layer = imgView.layer
layer.masksToBounds = true
layer.cornerRadius = radius
UIGraphicsBeginImageContext(imgView.bounds.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return roundedImage!
}
https://github.com/andreaantonioni/AAPhotoCircleCrop
Each view has an underlying layer onto which you apply a corner radius. Then you must apply clipToBounds on that layer in order to apply that mask to the overlying UIView. The corner radius must be half the width of the view in order to get a circle effect. Otherwise the corners of the view will be rounded.
For example:
let square = UIView()
square.center = view.center
square.bounds.size = CGSize(width: 100, height: 100)
square.backgroundColor = .red
view.addSubview(square)
square.layer.cornerRadius = 50
square.clipsToBounds = true
Above mentioned ways are good, But you can not achieved exact output as in above image E.g You can not get alpha effect.
I suggest simple way to do it.
1) Add new image to project with transparent background with Opocity and circle.
2) Add new imageView above to mainview as below.
let image = UIImageView(frame: view.bounds)
mage.image = UIImage.init(named:"imageName")
view.addSubview(image)
Then output should be as per your requirement.

How to use a color as a placeholder in UIImage

How can I use color as a placeholder in UIImage? For example I have an image like this:
And I want to change red to other image and receive something like this:
I thought about checking color of pixels and checking whether it's red and finding a frame, but maybe you know any better methods?
You need to take two View, one is UIView with a backgroundcolor of green(let us say), on that UIView you need to put your UIImageView, and you need to set the constraint according to that. Now set the background color of your UIImageView as red, and as per your requirement, check if the UIImageView's image is nil, if yes then you can add an image to your UIImageView.
Here is a function that will create a UIImage from the specified color. You can call this method with .red to generate the placeholder image you want.
static func image(fromColor color: UIColor) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
let renderer = UIGraphicsImageRenderer(bounds: rect)
let img = renderer.image { ctx in
ctx.cgContext.setFillColor(color.cgColor)
ctx.cgContext.fill(rect)
}
return img
}

How to tint an animated UIImageView?

I'm attempting to apply tint of a UIImageView consisting of programatically loaded animationImages. Currently using iOS 9.3.
I think I've tried every proposed solution found here for applying the tint including:
Setting the .renderMode on load with: let newImage: UIImage? =
UIImage(named: filename as
String)!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
Setting the tintView either in the Storyboard or programatically
with: zeroImageView.tintColor = UIColor.redColor()
Setting the image .renderMode through the UIImageView itself:
zeroImageView.image = zeroImageView.image!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
Setting the UIImageView's renderMode through the Interface Builder
user defined runtime attributes: imageRenderingMode Number 2
The image sequence is of PNGs with transparency, so, I would like to re-colour the image and maintain the transparency.
I've had no luck and am sort of at a loss. Wondering if maybe these methods only work for a still UIAnimationView? Any help would be greatly appreciated, thanks!
Here's some code:
// Load all images
while let element = enumerator.nextObject() as? String {
if element.hasSuffix("png") {
let filename: NSString = "Digits/0/" + element
print(filename)
imageNames.append(filename as String)
let newImage: UIImage? = UIImage(named: filename as String)!.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate)
images.append(newImage!)
zeroImageView.tintColor = UIColor.redColor()
}
}
// Make animated UIImageView
zeroImageView.userInteractionEnabled = false
zeroImageView.animationImages = images
zeroImageView.animationDuration = 2.0
zeroImageView.startAnimating()
zeroImageView.tintColor = UIColor.redColor()
Try this...
extension UIImage {
func image(withTint tint: UIColor) -> UIImage? {
guard let cgImage = cgImage else {
return nil
}
UIGraphicsBeginImageContextWithOptions(size, false, scale)
guard let context = UIGraphicsGetCurrentContext() else {
return nil
}
let rect = CGRect(origin: .zero, size: size)
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.setBlendMode(.normal)
context.clip(to: rect, mask: cgImage)
tint.setFill()
context.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
}
If none of those worked the next step I would do is programmatically place an empty UIView on top of the UIImageView. First off, it would not interfere with anything going on in the UIImageView.
I would check out this tutorial here: http://www.apptuitions.com/programmatically-creating-uiview-uislider-uiswitch-using-swift/
this will teach you how to programmatically add a UIView to the storyboard. I would add this code in the viewDidLoad() method.
The main thing you need to change is the background color of the UIView. First you have to decide what the color of the tint (which from what I see in your code is red) and then explicitly change the 'Alpha' of the color so that it is barely showing. You change the 'Alpha' because that is basically the opacity of the color.
Hope this helps.

Render an view into an image

I'm using the camera to take pictures and when i press a certain button the createImage method will be called. In here i'm trying to render an view called containerView into the image taken by the camera in previewImageView. However the issue is that the image in the camera is the size 1080x1920 and the containerView is a different size depending on the device. For instance on a iphone 6 it will be 375x503. How can i make sure that these two is rendered proberly together like in the below quick illustration?
in my code the containerView is very small in the bottom corner.
My Code at the moment
func createImage() -> UIImage {
//Get the taken image
let fullSizeImage = previewImageView.image
let newOverLayHeight = fullSizeImage!.size.width / self.containerView!.frame.width * self.containerView!.frame.height
print(newOverLayHeight)
//Render containerView to image
UIGraphicsBeginImageContext(CGSizeMake(fullSizeImage!.size.width, newOverLayHeight));
self.containerView!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let overlayImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Merge these two images
let newSize = CGSizeMake(fullSizeImage!.size.width, fullSizeImage!.size.height)
UIGraphicsBeginImageContext( newSize )
fullSizeImage!.drawInRect(CGRectMake(0,0,newSize.width,newSize.height))
//draw overlayImage on top of fullsizeImage
overlayImage.drawInRect(CGRectMake(0,fullSizeImage!.size.height - newOverLayHeight, overlayImage!.size.width,overlayImage.size.height), blendMode:CGBlendMode.Normal, alpha:1.0)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
return newImage
}
What i want

Resources