Saltar al contenido

¿Cómo dibujo en una imagen en Swift?

Si encuentras algún error en tu código o proyecto, recuerda probar siempre en un ambiente de testing antes añadir el código al trabajo final.

Solución:

Todo lo que necesita hacer es crear y obtener un objeto de contexto de imagen y acceder a todos sus poderosos métodos de dibujo. Puede obtener más información sobre el CGContext características del objeto aquí.

Esta función dibuja una línea y un círculo en un UIImage y devuelve la imagen modificada:

Rápido 4

func drawOnImage(_ image: UIImage) -> UIImage 
     
     // Create a context of the starting image size and set it as the current one
     UIGraphicsBeginImageContext(image.size)
     
     // Draw the starting image in the current context as background       
     image.draw(at: CGPoint.zero)

     // Get the current context
     let context = UIGraphicsGetCurrentContext()!

     // Draw a red line
     context.setLineWidth(2.0)
     context.setStrokeColor(UIColor.red.cgColor)
     context.move(to: CGPoint(x: 100, y: 100))
     context.addLine(to: CGPoint(x: 200, y: 200))
     context.strokePath()
     
     // Draw a transparent green Circle
     context.setStrokeColor(UIColor.green.cgColor)
     context.setAlpha(0.5)
     context.setLineWidth(10.0)
     context.addEllipse(in: CGRect(x: 100, y: 100, width: 100, height: 100))
     context.drawPath(using: .stroke) // or .fillStroke if need filling
     
     // Save the context as a new UIImage
     let myImage = UIGraphicsGetImageFromCurrentImageContext()
     UIGraphicsEndImageContext()
     
     // Return modified image
     return myImage

Es simple:

  1. Haz un contexto gráfico de imagen. (Antes de iOS 10, haría esto llamando UIGraphicsBeginImageContextWithOptions. En iOS 10 hay otra forma, UIGraphicsImageRenderer, pero no tiene que usarlo si no lo desea).

  2. Dibuja (es decir, copia) la imagen en el contexto. (UIImage en realidad tiene draw... métodos para este mismo propósito).

  3. Dibuja tu línea en el contexto. (Hay funciones CGContext para esto).

  4. Extrae la imagen resultante del contexto. (Por ejemplo, si usó UIGraphicsBeginImageContextWithOptions, usarías UIGraphicsGetImageFromCurrentImageContext.) Luego cierre el contexto.

Detalles

Xcode 9.1, Swift 4

Solución

extensión UIImage

extension UIImage 

    typealias RectCalculationClosure = (_ parentSize: CGSize, _ newImageSize: CGSize)->(CGRect)

    func with(image named: String, rectCalculation: RectCalculationClosure) -> UIImage 
        return with(image: UIImage(named: named), rectCalculation: rectCalculation)
    

    func with(image: UIImage?, rectCalculation: RectCalculationClosure) -> UIImage 

        if let image = image 
            UIGraphicsBeginImageContext(size)

            draw(in: CGRect(origin: .zero, size: size))
            image.draw(in: rectCalculation(size, image.size))

            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage!
        
        return self
    

extensión UIImageView

    extension UIImageView 

    enum ImageAddingMode 
        case changeOriginalImage
        case addSubview
    

    func drawOnCurrentImage(anotherImage: UIImage?, mode: ImageAddingMode, rectCalculation: UIImage.RectCalculationClosure) 

        guard let image = image else 
            return
        

        switch mode 
        case .changeOriginalImage:
            self.image = image.with(image: anotherImage, rectCalculation: rectCalculation)

        case .addSubview:
            let newImageView = UIImageView(frame: rectCalculation(frame.size, image.size))
            newImageView.image = anotherImage
            addSubview(newImageView)
        
    


Muestras de imágenes

Imagen de los padres:

ingrese la descripción de la imagen aquí

Imagen de niño:

ingrese la descripción de la imagen aquí


Ejemplo de uso 1

func sample1(imageView: UIImageView) 
    imageView.contentMode = .scaleAspectFit
    imageView.image = UIImage(named: "parent")?.with(image: "child")  parentSize, newImageSize in
        print("parentSize = (parentSize)")
        print("newImageSize = (newImageSize)")
        return CGRect(x: 50, y: 50, width: 90, height: 90)
    

Resultado 1

ingrese la descripción de la imagen aquí


Ejemplo de uso 2

func sample2(imageView: UIImageView) 
    imageView.contentMode = .scaleAspectFit
    imageView.image = UIImage(named: "parent")
    imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .changeOriginalImage)  parentSize, newImageSize in
        print("parentSize = (parentSize)")
        print("newImageSize = (newImageSize)")
        let sideLength:CGFloat = 90
        let indent:CGFloat = 50
        return CGRect(x: parentSize.width-sideLength-indent, y: parentSize.height-sideLength-indent, width: sideLength, height: sideLength)
    

Resultado 2

ingrese la descripción de la imagen aquí


Ejemplo de uso 3

func sample3(imageView: UIImageView) 
    imageView.contentMode = .scaleAspectFill
    imageView.clipsToBounds = true
    imageView.image = UIImage(named: "parent")
    imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .addSubview)  parentSize, newImageSize in
        print("parentSize = (parentSize)")
        print("newImageSize = (newImageSize)")
        let sideLength:CGFloat = 90
        let indent:CGFloat = 15
        return CGRect(x: parentSize.width-sideLength-indent, y: indent, width: sideLength, height: sideLength)
    

Resultado 3

ingrese la descripción de la imagen aquí

Código de muestra completo

No te olvides de agregar código de solución aquí

import UIKit

class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        let imageView = UIImageView(frame: UIScreen.main.bounds)
        view.addSubview(imageView)
        sample1(imageView: imageView)
       // sample2(imageView: imageView)
       // sample3(imageView: imageView)
    

    func sample1(imageView: UIImageView) 
        imageView.contentMode = .scaleAspectFit
        imageView.image = UIImage(named: "parent")?.with(image: "child")  parentSize, newImageSize in
            print("parentSize = (parentSize)")
            print("newImageSize = (newImageSize)")
            return CGRect(x: 50, y: 50, width: 90, height: 90)
        
    

    func sample2(imageView: UIImageView) 
        imageView.contentMode = .scaleAspectFit
        imageView.image = UIImage(named: "parent")
        imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .changeOriginalImage)  parentSize, newImageSize in
            print("parentSize = (parentSize)")
            print("newImageSize = (newImageSize)")
            let sideLength:CGFloat = 90
            let indent:CGFloat = 50
            return CGRect(x: parentSize.width-sideLength-indent, y: parentSize.height-sideLength-indent, width: sideLength, height: sideLength)
        
    

    func sample3(imageView: UIImageView) 
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        imageView.image = UIImage(named: "parent")
        imageView.drawOnCurrentImage(anotherImage: UIImage(named: "child"), mode: .addSubview)  parentSize, newImageSize in
            print("parentSize = (parentSize)")
            print("newImageSize = (newImageSize)")
            let sideLength:CGFloat = 90
            let indent:CGFloat = 15
            return CGRect(x: parentSize.width-sideLength-indent, y: indent, width: sideLength, height: sideLength)
        
    

Si te gustó nuestro trabajo, tienes la opción de dejar un ensayo acerca de qué le añadirías a este enunciado.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *