Reputation: 1603
I have a captured image from a device's camera and I want to add a UITextView
on it and then save it into the gallery. I'm using the following code to get an image from the text view
extension UITextView {
var imageOfView: UIImage {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}
Then, by using the following code, I try to add the above image to the taken image:
extension UIImage {
func combine(with image: UIImage, at point: CGPoint, isLandscapeMode: Bool = false) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, 0.0)
self.draw(at: .zero)
image.draw(at: point)
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return result!
}
}
finally, I call the method here to send the edited image to the previous page:
onImageEdited?(capturedImage.combine(with: textArea.imageOfView, at: textArea.frame.origin, isLandscapeMode: true))
Looking at the below screenshots, it's seen that the size changes and the position seem to be randomly chosen. Any idea why and how can I fix that?
During the editing:
After it's saved:
P.S: The captured image and the editing page are in Landscape mode
Upvotes: 0
Views: 338
Reputation: 1222
Try this one, I have commented the code which I have edited from the above code, please check it out and let me know it worked for you.
func stitchImages(images: [UIImage], isVertical: Bool) -> UIImage {
var stitchedImages : UIImage!
if images.count > 0 {
var maxWidth = CGFloat(0), maxHeight = CGFloat(0)
for image in images {
if image.size.width > maxWidth {
maxWidth = image.size.width
}
if image.size.height > maxHeight {
maxHeight = image.size.height
}
}
var totalSize : CGSize
let maxSize = CGSize(width: maxWidth, height: maxHeight)
if isVertical {
totalSize = CGSize(width: maxSize.width, height: maxSize.height * (CGFloat)(images.count))
} else {
totalSize = CGSize(width: maxSize.width, height: maxSize.height)
}
UIGraphicsBeginImageContext(totalSize)
let offset = (CGFloat)(0)
// Need to change or adjust the frame get get reach your reqirement
let rect1 = AVMakeRect(aspectRatio: images[1].size, insideRect: isVertical ? CGRect(x: 0, y: maxSize.height * offset, width: maxSize.width, height: maxSize.height) : CGRect(x: maxSize.width * offset, y: 0, width: maxSize.width, height: maxSize.height))
images[1].draw(in: rect1)
let rect2 = AVMakeRect(aspectRatio: images[0].size, insideRect: isVertical ? CGRect(x: 0, y: maxSize.height * offset, width: maxSize.width - 60, height: maxSize.height - 500) : CGRect(x: maxSize.width * offset, y: 250, width: maxSize.width - 60, height: maxSize.height - 500))
images[0].draw(in: rect2)
// for image in images {
// let offset = (CGFloat)(0)
// let rect = AVMakeRect(aspectRatio: image.size, insideRect: isVertical ?
// CGRect(x: 0, y: maxSize.height * offset, width: maxSize.width, height: maxSize.height) :
// CGRect(x: maxSize.width * offset, y: 0, width: maxSize.width, height: maxSize.height))
// image.draw(in: rect)
// }
stitchedImages = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
return stitchedImages
}
Upvotes: 0
Reputation: 949
func combine(text: String, withImage image: UIImage, atPoint point: CGPoint) -> UIImage? {
// Variables
let textColor = UIColor.white
let font = UIFont.systemFont(ofSize: 12)
let attributes: [NSAttributedStringKey: Any] = [
.foregroundColor: textColor,
.font: font
]
// Set scale and begin context
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
// Draw
image.draw(in: CGRect(origin: .zero, size: image.size))
let rect = CGRect(origin: point, size: image.size)
text.draw(in: rect, withAttributes: attributes)
// Get the new image
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
You could also create an extension for UIImageView
and render a new image from all of its subviews (e.x. the UITextView
)
extension UIImageView {
func renderSubviewsToImage() -> UIImage? {
guard let image = image else { return nil }
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
self.layer.render(in: context)
let renderedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return renderedImage
}
}
Upvotes: 0
Reputation: 1222
Try this code in Swift 4.2
func stitchImages(images: [UIImage], isVertical: Bool) -> UIImage {
var stitchedImages : UIImage!
if images.count > 0 {
var maxWidth = CGFloat(0), maxHeight = CGFloat(0)
for image in images {
if image.size.width > maxWidth {
maxWidth = image.size.width
}
if image.size.height > maxHeight {
maxHeight = image.size.height
}
}
var totalSize : CGSize
let maxSize = CGSize(width: maxWidth, height: maxHeight)
if isVertical {
totalSize = CGSize(width: maxSize.width, height: maxSize.height * (CGFloat)(images.count))
} else {
totalSize = CGSize(width: maxSize.width * (CGFloat)(images.count), height: maxSize.height)
}
UIGraphicsBeginImageContext(totalSize)
for image in images {
let offset = (CGFloat)(images.index(of: image)!)
let rect = AVMakeRect(aspectRatio: image.size, insideRect: isVertical ?
CGRect(x: 0, y: maxSize.height * offset, width: maxSize.width, height: maxSize.height) :
CGRect(x: maxSize.width * offset, y: 0, width: maxSize.width, height: maxSize.height))
image.draw(in: rect)
}
stitchedImages = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
return stitchedImages
}
}
and you can use this:
@IBOutlet weak var imageView: UIImageView!
let imageArray = [image1, image3, image4, image4]
override func viewDidLoad() {
super.viewDidLoad()
let image = stitchImages(images: imageArray, isVertical: false)
imageView.image = image
}
Upvotes: 1