How can I get spesific tableviewcell screenshot with navigationbar? - ios

I'm trying to get screenshot of uitableviewcell and I can succesfully do it. But I cannot append the navigationbar top of the UIImage.
This is what i have:
https://i.imgur.com/8ULUFg5.jpg
This is what i want to get:
https://i.imgur.com/w0IpoYA.png
How can i append navigation bar to image?
I've tried to create new UIImage for create merged image but it doesn't work.
At the below there is my code for get cell's screenshot properly.
let cell = self.entryView.cellForRow(at: self.indexP) as! entryViewTableCell
let frame = cell.frame
let kalan = self.indexP.row % 2
cell.entryText.backgroundColor = (kalan == 0) ? Theme.cellFirstColor : Theme.cellSecondColor
cell.entryText.text = ""
UIGraphicsBeginImageContextWithOptions(cell.entryText.frame.size, true, 2)
cell.entryText.attributedText = self.entryler[self.indexP.row]
cell.entryText.textColor = Theme.labelColor
cell.entryText.tintColor = Theme.linkColor
cell.entryText.layer.render(in: UIGraphicsGetCurrentContext()!)
let snapshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
edit:
https://i.imgur.com/OR4gV6L.jpg
I can get this image with below code, but navigationbar opacity too low. How can I opaque it?
let cell = self.entryView.cellForRow(at: self.indexP) as! entryViewTableCell
let frame = cell.entryText.frame
let kalan = self.indexP.row % 2
cell.entryText.backgroundColor = (kalan == 0) ? Theme.cellFirstColor : Theme.cellSecondColor
cell.entryText.text = ""
UIGraphicsBeginImageContextWithOptions(frame.size, true, 2)
cell.entryText.attributedText = self.entryler[self.indexP.row]
cell.entryText.textColor = Theme.labelColor
cell.entryText.tintColor = Theme.linkColor
cell.entryText.layer.render(in: UIGraphicsGetCurrentContext()!)
let snapshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIGraphicsBeginImageContextWithOptions((self.navigationController?.navigationBar.layer.frame.size)!, true, 2)
self.navigationController?.navigationBar.drawHierarchy(in: (self.navigationController?.navigationBar.bounds)!, afterScreenUpdates: false)
self.navigationController?.navigationBar.layer.render(in: UIGraphicsGetCurrentContext()!)
let ss = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let img = self.getMixedImg(image1: ss!, image2: snapshot!)
func getMixedImg(image1: UIImage, image2: UIImage) -> UIImage? {
let size = CGSize(width: image1.size.width, height: image1.size.height + image2.size.height)
UIGraphicsBeginImageContextWithOptions(size, true, 2)
image1.draw(in: CGRect(x: 0,y: 0,width: size.width, height: image1.size.height))
image2.draw(in: CGRect(x: 0,y: image1.size.height,width: size.width, height: image2.size.height))
let finalImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return finalImage
}

This is answer for my question:
let cell = self.entryView.cellForRow(at: self.indexP) as! entryViewTableCell
let frame = cell.entryText.frame
let kalan = self.indexP.row % 2
cell.entryText.backgroundColor = (kalan == 0) ? Theme.cellFirstColor : Theme.cellSecondColor
cell.entryText.text = ""
UIGraphicsBeginImageContextWithOptions(frame.size, true, 3)
cell.entryText.attributedText = self.entryler[self.indexP.row]
cell.entryText.textColor = Theme.labelColor
cell.entryText.tintColor = Theme.linkColor
cell.entryText.layer.render(in: UIGraphicsGetCurrentContext()!)
let snapshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIGraphicsBeginImageContextWithOptions((self.navigationController?.navigationBar.layer.bounds.size)!, true, 3)
self.navigationController?.navigationBar.drawHierarchy(in: (self.navigationController?.navigationBar.layer.bounds)!, afterScreenUpdates: false)
let ss = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let img = self.getMixedImg(image1: ss!, image2: snapshot!)
func getMixedImg(image1: UIImage, image2: UIImage) -> UIImage? {
let size = CGSize(width: image1.size.width, height: image1.size.height + image2.size.height)
UIGraphicsBeginImageContextWithOptions(size, true, 2)
image1.draw(in: CGRect(x: 0,y: 0,width: size.width, height: image1.size.height))
image2.draw(in: CGRect(x: 0,y: image1.size.height,width: size.width, height: image2.size.height))
let finalImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return finalImage
}
and result: https://i.imgur.com/ezcfxnw.jpg

Related

How to make image to watermarkimage in swift [duplicate]

I know there are several other ways to do this; I don't want to import anything that I don't need to. If someone can help me with his code, that would be great.
Currently, it is only saving the original image without the watermark image.
extension UIImage {
class func imageWithWatermark(image1: UIImageView, image2: UIImageView) -> UIImage {
UIGraphicsBeginImageContextWithOptions(image1.bounds.size, false, 0.0)
image2.layer.renderInContext(UIGraphicsGetCurrentContext()!)
image1.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}
}
func addWatermark() {
let newImage = UIImage.imageWithWatermark(imageView, image2: watermarkImageView)
UIImageWriteToSavedPhotosAlbum(newImage, nil, nil, nil)
}
EDIT: I've got the watermark appearing on the saved images.
I had to switch the order of the layers:
image1.layer.renderInContext(UIGraphicsGetCurrentContext()!)
image2.layer.renderInContext(UIGraphicsGetCurrentContext()!)
HOWEVER, it is not appearing in the correct place.It seems to always appear in the center of the image.
If you grab the UIImageViews' images you could use the following concept:
if let img = UIImage(named: "image.png"), img2 = UIImage(named: "watermark.png") {
let rect = CGRect(x: 0, y: 0, width: img.size.width, height: img.size.height)
UIGraphicsBeginImageContextWithOptions(img.size, true, 0)
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor)
CGContextFillRect(context, rect)
img.drawInRect(rect, blendMode: .Normal, alpha: 1)
img2.drawInRect(CGRectMake(x,y,width,height), blendMode: .Normal, alpha: 1)
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(result, nil, nil, nil)
}
SWIFT 4
Use this
let backgroundImage = imageData!
let watermarkImage = #imageLiteral(resourceName: "jodi_url_icon")
let size = backgroundImage.size
let scale = backgroundImage.scale
UIGraphicsBeginImageContextWithOptions(size, false, scale)
backgroundImage.draw(in: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
watermarkImage.draw(in: CGRect(x: 10, y: 10, width: size.width, height: size.height - 40))
let result = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
Use result to UIImageView, tested.

how to layer an image over another

My code below kind of works but the frame is not symmetrical and I am using 2 images let bottomImage and let frame and only let frame should be used. To give you a example check out the image below I created. Frame should take the place of the black border.
#IBAction func Mask(_ sender: Any) {
let bottomImage:UIImage = UIImage(named: "backdropd")!
let frame:UIImage = UIImage(named: "ff")!
let newSize = CGSize(width: bottomImage.size.width, height: bottomImage.size.height )
let newSize2 = CGSize(width: bottomImage.size.width, height: bottomImage.size.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, bottomImage.scale)
let left:UIImage = imageTake.image!
left.draw(in: CGRect(x: newSize2.width/7,y: newSize2.height/8.9,width: newSize2.width/1,height: newSize2.height/1.29), blendMode:CGBlendMode.normal, alpha:1.0)
frame.draw(in: CGRect(x: 0,y: 0,width: newSize2.width,height: newSize2.height), blendMode:CGBlendMode.normal, alpha:1.0)
let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
imageTake.image = newImage
}

Screenshot a view with label and transparent background in iOS and upload it to server

I want to screenshot a view and create an UIImage from it. I want the transparency attribute of the view to be maintained in my image. I tried this method after creating an extension of UIImage but the background is not transparent in the resultant image when uploaded to the server.
Kindly help or point me if I am doing something wrong!! This means that the resultant png was not having transparency.
class func createTransparentImageFrom(label: UILabel, imageSize: CGSize) -> UIImage {
UIGraphicsBeginImageContextWithOptions(imageSize, false, 2.0)
let currentView = UIView.init(frame: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
currentView.backgroundColor = UIColor.clear
currentView.addSubview(label)
currentView.layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img!
}
This was due to the fact that when we render a view the image is JPEG/JPG, so we need to convert it to png in order to get layer information.
Try this :
extension UIImage {
class func createTransparentPNGFrom(label: UILabel, imageSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
let currentView = UIView.init(frame: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
currentView.backgroundColor = UIColor.clear
currentView.addSubview(label)
currentView.layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let newImg = img else {
return nil
}
guard let imageData = UIImagePNGRepresentation(newImg) else {
return nil
}
return UIImage.init(data: imageData)
}
}
Swift 5 UIImage extension: screen UIView with transparent background
this is for taking a screenshot of a view which should have .backgroundColor = .clear
extension UIView {
func takeSnapshotOfView() -> UIImage? {
let size = CGSize(width: frame.size.width, height: frame.size.height)
let rect = CGRect.init(origin: .init(x: 0, y: 0), size: frame.size)
UIGraphicsBeginImageContext(size)
drawHierarchy(in: rect, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let imageData = image?.pngData() else {
return nil
}
return UIImage.init(data: imageData)
}
}
You need to put opaque value true for transparent result
Extension of UIView Of transparent screenshot
func screenShot() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, UIScreen.main.scale)
self.layer.render(in: UIGraphicsGetCurrentContext()!)
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return img
}

UIImage masking doesn't work (Swift, iOS 10)

Trying to mask an image with my custom mask. I think I follow the ideas correctly, but for some reason, image isn't get masked. Instead, masked image, created after masking, contains original cropped image as the mask wasn't applied.
Here's the Swift playground code which one can use in order to test my code (image and mask are attached, just drop them to the resources folder):
import UIKit
extension UIImage {
static func resizeImage(image: UIImage, width: CGFloat) -> UIImage {
let scale = width / image.size.width
let newHeight = round(image.size.height * scale)
UIGraphicsBeginImageContextWithOptions(CGSize(width:width, height:newHeight), false, image.scale)
image.draw(in: CGRect(origin: CGPoint(x:0, y:0), size: CGSize(width: width, height: newHeight)))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
static func resizeImage(image: UIImage, height: CGFloat) -> UIImage {
let scale = height / image.size.height
let newWidth = round(image.size.width * scale)
UIGraphicsBeginImageContextWithOptions(CGSize(width:newWidth, height:height), false, image.scale)
image.draw(in: CGRect(origin: CGPoint(x:0, y:0), size: CGSize(width: newWidth, height: height)))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
let image = UIImage(named: "image.jpg")!
var mask = UIImage(named: "mask.jpg")!
let k1 = image.size.width / image.size.height
let k2 = mask.size.width / mask.size.height
if k1 >= k2
{
mask = UIImage.resizeImage(image: mask, height: image.size.height)
}
else
{
mask = UIImage.resizeImage(image: mask, width: image.size.width)
}
image
mask
let center = CGPoint(x: image.size.width/2, y: image.size.height/2)
let croppingRect = CGRect(x: abs(image.size.width-mask.size.width)/2*image.scale,
y: abs(image.size.height-mask.size.height)/2*image.scale,
width: mask.size.width*image.scale,
height: mask.size.height*image.scale).integral
let maskReference = mask.cgImage!
let imageReference = image.cgImage!.cropping(to: croppingRect)!
let imageMask = CGImage(maskWidth: maskReference.width,
height: maskReference.height,
bitsPerComponent: maskReference.bitsPerComponent,
bitsPerPixel: maskReference.bitsPerPixel,
bytesPerRow: maskReference.bytesPerRow,
provider: maskReference.dataProvider!, decode: nil, shouldInterpolate: true)
imageMask?.colorSpace
imageMask?.alphaInfo
let maskedReference = imageReference.masking(imageMask!)
let maskedImage = UIImage(cgImage:maskedReference!, scale: image.scale, orientation: image.imageOrientation)
Swift 4+
let icon = UIImageView(image: YOURIMAGE)
icon.frame = CGRect(x:100, y: 100, width: 100, height: 100)
icon.layer.masksToBounds = true
let maskView = UIImageView()
maskView.image = YOURMASKIMAGE
maskView.frame = icon.bounds
icon.mask = maskView
icon.contentMode = .scaleToFill
icon.clipsToBounds = true
view.addSubview(icon)

merge two different images in Swift

I want to merge two UIImage in Swift:
and
I tried it with
func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage {
let maskRef = maskImage.CGImage
let mask = CGImageMaskCreate(
CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef),
nil,
false)
let masked = CGImageCreateWithMask(image.CGImage, mask)
let maskedImage = UIImage(CGImage: masked!)
// No need to release. Core Foundation objects are automatically memory managed.
return maskedImage
}
and the call
let imageName = data.valueForKey("imagename")!.description
let image = UIImage(named: imageName)
let imageBackground : UIImage = UIImage(named:"background")!
let maskedImage: UIImage = self.maskImage(image!, withMask: imageBackground)
cell.imageButton.setImage(maskedImage, forState: .Normal)
the result is just the image that i get with let image = UIImage(named: imageName), the second image (volleyball)
What´s my error?
If you don't care about performance you can use Core Image
let volleyballImage = CIImage(image: UIImage(named:"volleyball.png")!)
let otherImage = CIImage(image: UIImage(named:"other.png")!)
let compositeFilter = CIFilter(name: "CIAdditionCompositing")!
compositeFilter.setValue(volleyballImage,
forKey: kCIInputImageKey)
compositeFilter.setValue(otherImage,
forKey: kCIInputBackgroundImageKey)
if let compositeImage = compositeFilter.outputImage{
let image = UIImage(CIImage: compositeImage)
// do something with the "merged" image
}
You can do it in few lines:
var bottomImage:UIImage = UIImage(named: "imageName")!
var topImage:UIImage = UIImage(named:"background")!
// Change here the new image size if you want
var newSize = CGSizeMake(bottomImage.size.width, bottomImage.size.height)
UIGraphicsBeginImageContextWithOptions(newSize, false, bottomImage.scale)
bottomImage.drawInRect(CGRectMake(0,0,newSize.width,newSize.height))
topImage.drawInRect(CGRectMake(0,0,newSize.width,newSize.height), blendMode:CGBlendMode.Normal, alpha:1.0)
var newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
You can use my simple method to merge two images in half.
Like this:
func mergeTwoImage(leftImg:UIImage,rightImg:UIImage) -> UIImage?{
let size = CGSize(width: leftImg.size.width, height: leftImg.size.height)
UIGraphicsBeginImageContext(size)
let area1 = CGRect(x: 0, y: 0, width: size.width, height: size.height)
let area2 = CGRect(x: size.width/2, y: 0, width: size.width, height: size.height)
leftImg.draw(in: area1)
rightImg.draw(in: area2, blendMode: .normal, alpha: 1)
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return finalImage
}

Resources