UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Project 27: Core Graphics - Images and text

Forums > Swift

Hello,

my first project is a camera, taking pictures and saving these into the camera roll, which works as expected. Now I am trying to add a custom watermark as text to every picture before saving.

I found the example Project 27 (mouse and text). The idea is to use the camera picture instead of the mouse, add the text and save it:

func drawImagesAndText(_ photo: AVCapturePhoto) -> UIImage {
    // 1
    let renderer = UIGraphicsImageRenderer(size: CGSize(width: 512, height: 512))
    // let renderer = UIGraphicsImageRenderer(size: CGSize(width: photo.size.width, height: photo.size.height))

    let img = renderer.image { ctx in
        // 2
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.alignment = .center

        // 3
        let attrs: [NSAttributedString.Key: Any] = [
            .font: UIFont.systemFont(ofSize: 36),
            .paragraphStyle: paragraphStyle
        ]

        // 4
        let string = "The best-laid schemes o'\nmice an' men gang aft agley"
        let attributedString = NSAttributedString(string: string, attributes: attrs)

        // 5
        attributedString.draw(with: CGRect(x: 32, y: 32, width: 448, height: 448), options: .usesLineFragmentOrigin, context: nil)

        // 5
        // let mouse = UIImage(named: "mouse")
        guard let mouse = UIImage(data: photo.fileDataRepresentation()!) else {
            print("Unable to generate UIImage from image data.");
            // self.lastPhoto = nil;
            return
        }
        mouse.draw(at: CGPoint(x: 0, y: 0))
    }

    // 6
    return img
}

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

    DispatchQueue.main.async {
        self.photoProcessingHandler(false)
    }

    if let error = error {
        print("Error capturing photo: \(error)")
    } else {
        // photoData = photo.fileDataRepresentation()
        photoData = drawImagesAndText(photo).pngData()

    }
}

My source code has two main issues:

  1. I can not find the size of the AVCapturePhoto, thus a fixed size is used (line 3+4). Creating the UIImage at the beginning of the function results in memory exceeded. How can I access the size of the AVCapturePhoto?

  2. Variable photoData (line 48,49) has the type Data?. According to the documentation, photo.fileDataRepresentation() can represent different types like HEIF. But UIImage does only offer jpg or png, how can I convert it back to the new image format?

Am I trying it completely wrong? Do I using the wrong frameworks and should I use AVCamFilter instead?

I would be very grateful, if I somebody has a hint so I can fix the code and complete my project.

Best regards Tobias

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.