user7459574
user7459574

Reputation:

How to transform and enlarge imageview into a shape (swift3)

What I am trying to do is take a square imageview and make it a 5 point imageview in the shape of a 3 point triangle at the top and the bottom to points in a base.

enter image description here

public func shapeImage(with bezierPath: UIBezierPath, size: CGSize, fillColor: UIColor? = UIColor.clear,
                         strokeColor: UIColor? = nil, strokeWidth: CGFloat = 0.0) -> UIImage! {

UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
var image = UIImage(data: try! Data(contentsOf: URL(string:"https://a248.e.akamai.net/secure.meetupstatic.com/photos/member/5/3/5/e/highres_260901342.jpeg")!))!

if let context = context {
    context.saveGState()
    context.addPath(bezierPath.cgPath)

    if let strokeColor = strokeColor {
        strokeColor.setStroke()
        context.setLineWidth(strokeWidth)
    } else {
        UIColor.clear.setStroke()
    }

    fillColor?.setFill()
    context.drawPath(using: .fillStroke)

    image = UIGraphicsGetImageFromCurrentImageContext()!
    context.restoreGState()
    UIGraphicsEndImageContext()
}
return image

}

I want to take the top and make it bigger and keep the bottom half the same size. I do not want to mask or cut of some portion of the original image. I want to physical make the image bigger by stretching and not masking. I have not seen anything on this site that explains how to do this or if its possible.

Upvotes: 2

Views: 716

Answers (3)

Johannes Knust
Johannes Knust

Reputation: 1021

I really don't see the problem to create one more point in a new BezierPath and draw a new Image with the same fillColor, Stroke etc .. You could use an extension like this one ...

public class func shapeImage(with bezierPath: UIBezierPath, size: CGSize, fillColor: UIColor? = UIColor.clear,
                             strokeColor: UIColor? = nil, strokeWidth: CGFloat = 0.0) -> UIImage! {

    UIGraphicsBeginImageContext(size)
    let context = UIGraphicsGetCurrentContext()
    var image = UIImage()
    if let context = context {
        context.saveGState()
        context.addPath(bezierPath.cgPath)

        if let strokeColor = strokeColor {
            strokeColor.setStroke()
            context.setLineWidth(strokeWidth)
        } else {
            UIColor.clear.setStroke()
        }

        fillColor?.setFill()
        context.drawPath(using: .fillStroke)

        image = UIGraphicsGetImageFromCurrentImageContext()!
        context.restoreGState()
        UIGraphicsEndImageContext()
    }
    return image
}

Upvotes: 0

Jon Rose
Jon Rose

Reputation: 8563

If you don't want to crop with a mask you will have a very strange distorted image. If you are really really sure that is what you want you can use https://github.com/Ciechan/BCMeshTransformView to first move all the points down, then animate it to move only the center point up. something like:

BCMeshVertex vertices[] = {
    {.from = {0.0, 0.0}, .to= {0.0, 0.5, 0.0}},
    {.from = {1.0, 0.0}, .to= {1.0, 0.5, 0.0}},
    {.from = {1.0, 1.0}, .to= {1.0, 1.0, 0.0}},
    {.from = {0.0, 1.0}, .to= {0.0, 1.0, 0.0}},
};

and then when you want to turn it into a house update the vectors to:

BCMeshVertex vertices[] = {
    {.from = {0.0, 0.0}, .to= {0.0, 0.5, 0.0}},
    {.from = {0.5, 0.0}, .to= {0.0, 0.0, 0.0}},
    {.from = {1.0, 0.0}, .to= {1.0, 0.5, 0.0}},
    {.from = {1.0, 1.0}, .to= {1.0, 1.0, 0.0}},
    {.from = {0.0, 1.0}, .to= {0.0, 1.0, 0.0}},
};

This will make a weird mesh, warp effect like Warp \ bend effect on a UIView? - which is am pretty sure will look very very ugly. But that is what you asked for. (There is a MUCH simpler solution using a CAShapeLayer to mask the image).

Upvotes: 2

Sagar Bhut
Sagar Bhut

Reputation: 657

you can refer that

https://www.innofied.com/implementing-image-masking-in-ios/

when any problem in this i provide code for that but, now you show that help you or not..i try my best..

example:

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let image = UIImage(named: "image.gif")
        let maskingImage = UIImage(named: "mask-image.gif")
        imageView.image = maskImage(image: image!, mask: maskingImage!)
    }

        func maskImage(image:UIImage, mask:(UIImage))->UIImage{

        let imageReference = image.cgImage
        let maskReference = mask.cgImage

        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)

        let maskedReference = imageReference!.masking(imageMask!)

        let maskedImage = UIImage(cgImage:maskedReference!)

        return maskedImage
    }
}

Upvotes: 0

Related Questions