Добавить текст к изображению в цикле Swift - PullRequest
0 голосов
/ 26 марта 2019

Я добавляю текст в массив изображений, используя swift.Ниже приведен мой код для цикла:

var holderClass = HolderClass()
var newImages = [UIImage]()
var counter = 0
for (index, oldImage) in holderClass.oldImages.enumerated(){
        let newImage = drawTextAtLoaction(text: "testing", image: oldImage)
        newImages[index] = newImage
        counter+=1
        if(counter == self.storyModule.getImageCount()){
            completionHandler(newImages)
        }
}

Вот функция добавления текста:

func drawTextAtLoaction(text: String, image: UIImage) -> UIImage{
    let textColor = UIColor.white
    let textFont = UIFont(name: "Helvetica Bold", size: 12)!
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(image.size, false, scale)

    let textFontAttributes = [
        NSAttributedString.Key.font: textFont,
        NSAttributedString.Key.foregroundColor: textColor,
        ] as [NSAttributedString.Key : Any]
    image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
    let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: image.size)
    text.draw(in: rect, withAttributes: textFontAttributes)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    if newImage != nil{
        return newImage!
    }else{
        return image
    }
}

Интуитивно, этот цикл должен занимать постоянную память, однако, как показано на следующем рисункезанимает линейное хранилище и вызывает ошибки памяти с большим количеством изображений.

Allocation instrument

Как использовать постоянную память для такой операции?

edit: я думаю, что я, возможно, немного упростил это.Массив oldImages на самом деле является массивом изображений внутри объекта.Таким образом, инициализация старых изображений выглядит следующим образом.

class HolderClass{
    private var oldImages: [UIImage]!
    init(){
      oldImages = [UIImage(), UIImage()]
    }
}

edit 2: Так загружаются данные изображения.Следующий код находится в viewDidLoad.

var holderClass = HolderClass()
DispatchQueue.global(qos: .background).async {
    var dataIntermediate = [StoryData]()
    let dataRequest:NSFetchRequest<StoryData> = StoryData.fetchRequest()
    do {
        dataIntermediate = try self.managedObjectContext.fetch(dataRequest)
        for storyData in dataIntermediate{
            var retrievedImageArray = [UIImage]()
            if let loadedImage = DocumentSaveManager.loadImageFromPath(imageId: Int(storyData.id)){
                retrievedImageArray.append(loadedImage)
            }
            holderData.oldImages = retrievedImageArray
        }
    }catch{
        print("Failed to load data \(error.localizedDescription)")
    }
}

Это класс DocumentSaveManager.

static func documentDirectoryURL() -> URL {
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    return documentsURL
}

static func saveInDocumentsDirectory(foldername:String, filename: String) -> URL {
    let fileURL = documentDirectoryURL().appendingPathComponent(foldername).appendingPathComponent(filename)
    return fileURL
}

static func loadImageFromPath(moduleId: Int, imageId: Int) -> UIImage? {
    let path = saveInDocumentsDirectory(foldername: String(describing: moduleId), filename: String(describing: imageId)).path
    let image = UIImage(contentsOfFile: path)
    if image == nil {
        return nil // Remember to alert user
    }
    return image
}
...