Как добавить текст в CIImage?

Я работаю с фреймворком Photos и создал приложение, которое будет применять фильтр к изображению. Теперь вместо применения фильтра я хочу добавить текст поверх изображения. Этот API предоставляет мне CIImage, который я могу использовать для создания выходных данных CIImage. Я просто не знаю, как добавить текст в определенное место в файл CIImage. Если я прав, не рекомендуется преобразовывать его в CGImage, а затем добавлять текст из-за снижения производительности.

Как можно работать с существующим CIImage для вывода точно такого же CIImage (с сохранением исходного качества изображения) с текстом, наложенным сверху в определенном месте?

//Get full image
let url = contentEditingInput.fullSizeImageURL
let orientation = contentEditingInput.fullSizeImageOrientation
var inputImage = CIImage(contentsOfURL: url)
inputImage = inputImage.imageByApplyingOrientation(orientation)

//TODO: REPLACE WITH TEXT OVERLAY
/*//Add filter
let filterName = "CISepiaTone"
let filter = CIFilter(name: filterName)
filter.setDefaults()
filter.setValue(inputImage, forKey: kCIInputImageKey)
let outputImage: CIImage = filter.outputImage*/

//Create editing output
let jpegData: NSData = self.jpegRepresentationOfImage(outputImage)
let adjustmentData = PHAdjustmentData(formatIdentifier: AdjustmentFormatIdentifier, formatVersion: "1.0", data: filterName.dataUsingEncoding(NSUTF8StringEncoding))

let contentEditingOutput = PHContentEditingOutput(contentEditingInput: contentEditingInput)
jpegData.writeToURL(contentEditingOutput.renderedContentURL, atomically: true)
contentEditingOutput.adjustmentData = adjustmentData

PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in
    let request = PHAssetChangeRequest(forAsset: asset)
request.contentEditingOutput = contentEditingOutput
}, completionHandler: { (success: Bool, error: NSError!) -> Void in
    if !success {
        NSLog("Error saving image: %@", error)
    }
})

person Jordan H    schedule 01.09.2014    source источник


Ответы (2)


Вы можете нарисовать текст в оттенках серого в отдельный CGImage, преобразовать CGImage в CIImage (через [+CIImage imageWithCGImage:]), а затем используйте его в качестве маски, отправив его и исходный CIImage в CIBlendWithMask< /а> фильтр.

person user1118321    schedule 02.09.2014
comment
Красивый. Как раз то, что я искал! - person Jordan H; 02.09.2014
comment
любой пример в быстром? - person user924; 01.03.2018

С прошлого года доступен новый CIFilter под названием CIAttributedTextImageGenerator. Вот пример того, как я его использовал, завернутый в метод служебного класса:

+ (CIImage *)imageWithText:(NSString *)message color:(CIColor *)color scaleFactor:(CGFloat)scaleFactor
{
    NSDictionary *attributes = @{
        NSForegroundColorAttributeName : CFBridgingRelease(CGColorCreateSRGB(color.red, color.green, color.blue, color.alpha)),
    };
    NSAttributedString *text = [[NSAttributedString alloc] initWithString:message attributes:attributes];

    CIFilter<CIAttributedTextImageGenerator> *filter = [CIFilter attributedTextImageGeneratorFilter];
    filter.text = text;
    filter.scaleFactor = scaleFactor;

    CIImage *result = filter.outputImage;
    return result;
}

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

В любом случае, это создаст CIImage, который затем можно будет наложить на inputImage следующим образом:

CIImage *textImage = [YourUtilityClass imageWithText:@"Some text" color:[CIColor whiteColor] scaleFactor:1.0];
CIImage *outputImage = [textImage imageByCompositingOverImage:inputImage];

У меня не так много опыта работы со Swift в последнее время, но, надеюсь, этот код на Objective-C достаточно прост, чтобы вы поняли идею.

person Stephen    schedule 01.09.2020