Various fixes

This commit is contained in:
Ilya Laktyushin
2023-07-25 22:37:45 +02:00
parent f4fc72b762
commit ab6b0140cd
17 changed files with 379 additions and 77 deletions

View File

@@ -42,6 +42,7 @@ final class MediaEditorComposer {
private let values: MediaEditorValues
private let dimensions: CGSize
private let outputDimensions: CGSize
private let textScale: CGFloat
private let ciContext: CIContext?
private var textureCache: CVMetalTextureCache?
@@ -53,10 +54,11 @@ final class MediaEditorComposer {
private let drawingImage: CIImage?
private var entities: [MediaEditorComposerEntity]
init(account: Account, values: MediaEditorValues, dimensions: CGSize, outputDimensions: CGSize) {
init(account: Account, values: MediaEditorValues, dimensions: CGSize, outputDimensions: CGSize, textScale: CGFloat) {
self.values = values
self.dimensions = dimensions
self.outputDimensions = outputDimensions
self.textScale = textScale
let colorSpace = CGColorSpaceCreateDeviceRGB()
self.colorSpace = colorSpace
@@ -77,7 +79,7 @@ final class MediaEditorComposer {
var entities: [MediaEditorComposerEntity] = []
for entity in values.entities {
entities.append(contentsOf: composerEntitiesForDrawingEntity(account: account, entity: entity.entity, colorSpace: colorSpace))
entities.append(contentsOf: composerEntitiesForDrawingEntity(account: account, textScale: textScale, entity: entity.entity, colorSpace: colorSpace))
}
self.entities = entities
@@ -155,7 +157,7 @@ final class MediaEditorComposer {
CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &pixelBuffer)
if let pixelBuffer, let context = self.ciContext {
makeEditorImageFrameComposition(context: context, inputImage: image, gradientImage: self.gradientImage, drawingImage: self.drawingImage, dimensions: self.dimensions, values: self.values, entities: self.entities, time: time, completion: { compositedImage in
makeEditorImageFrameComposition(context: context, inputImage: image, gradientImage: self.gradientImage, drawingImage: self.drawingImage, dimensions: self.dimensions, outputDimensions: self.outputDimensions, values: self.values, entities: self.entities, time: time, completion: { compositedImage in
if var compositedImage {
let scale = self.outputDimensions.width / self.dimensions.width
compositedImage = compositedImage.samplingLinear().transformed(by: CGAffineTransform(scaleX: scale, y: scale))
@@ -176,11 +178,11 @@ final class MediaEditorComposer {
guard let context = self.ciContext else {
return
}
makeEditorImageFrameComposition(context: context, inputImage: inputImage, gradientImage: self.gradientImage, drawingImage: self.drawingImage, dimensions: self.dimensions, values: self.values, entities: self.entities, time: time, completion: completion)
makeEditorImageFrameComposition(context: context, inputImage: inputImage, gradientImage: self.gradientImage, drawingImage: self.drawingImage, dimensions: self.dimensions, outputDimensions: self.outputDimensions, values: self.values, entities: self.entities, time: time, textScale: self.textScale, completion: completion)
}
}
public func makeEditorImageComposition(context: CIContext, account: Account, inputImage: UIImage, dimensions: CGSize, values: MediaEditorValues, time: CMTime, completion: @escaping (UIImage?) -> Void) {
public func makeEditorImageComposition(context: CIContext, account: Account, inputImage: UIImage, dimensions: CGSize, values: MediaEditorValues, time: CMTime, textScale: CGFloat, completion: @escaping (UIImage?) -> Void) {
let colorSpace = CGColorSpaceCreateDeviceRGB()
let inputImage = CIImage(image: inputImage, options: [.colorSpace: colorSpace])!
let gradientImage: CIImage
@@ -197,10 +199,10 @@ public func makeEditorImageComposition(context: CIContext, account: Account, inp
var entities: [MediaEditorComposerEntity] = []
for entity in values.entities {
entities.append(contentsOf: composerEntitiesForDrawingEntity(account: account, entity: entity.entity, colorSpace: colorSpace))
entities.append(contentsOf: composerEntitiesForDrawingEntity(account: account, textScale: textScale, entity: entity.entity, colorSpace: colorSpace))
}
makeEditorImageFrameComposition(context: context, inputImage: inputImage, gradientImage: gradientImage, drawingImage: drawingImage, dimensions: dimensions, values: values, entities: entities, time: time, completion: { ciImage in
makeEditorImageFrameComposition(context: context, inputImage: inputImage, gradientImage: gradientImage, drawingImage: drawingImage, dimensions: dimensions, outputDimensions: dimensions, values: values, entities: entities, time: time, textScale: textScale, completion: { ciImage in
if let ciImage {
if let cgImage = context.createCGImage(ciImage, from: CGRect(origin: .zero, size: ciImage.extent.size)) {
Queue.mainQueue().async {
@@ -213,7 +215,7 @@ public func makeEditorImageComposition(context: CIContext, account: Account, inp
})
}
private func makeEditorImageFrameComposition(context: CIContext, inputImage: CIImage, gradientImage: CIImage, drawingImage: CIImage?, dimensions: CGSize, values: MediaEditorValues, entities: [MediaEditorComposerEntity], time: CMTime, completion: @escaping (CIImage?) -> Void) {
private func makeEditorImageFrameComposition(context: CIContext, inputImage: CIImage, gradientImage: CIImage, drawingImage: CIImage?, dimensions: CGSize, outputDimensions: CGSize, values: MediaEditorValues, entities: [MediaEditorComposerEntity], time: CMTime, textScale: CGFloat = 1.0, completion: @escaping (CIImage?) -> Void) {
var resultImage = CIImage(color: .black).cropped(to: CGRect(origin: .zero, size: dimensions)).transformed(by: CGAffineTransform(translationX: -dimensions.width / 2.0, y: -dimensions.height / 2.0))
resultImage = gradientImage.composited(over: resultImage)
@@ -267,8 +269,10 @@ private func makeEditorImageFrameComposition(context: CIContext, inputImage: CII
image = image.transformed(by: resetTransform)
var baseScale: CGFloat = 1.0
if let entityBaseScale = entity.baseScale {
baseScale = entityBaseScale
if let scale = entity.baseScale {
baseScale = scale
} else if let _ = entity.baseDrawingSize {
// baseScale = textScale
} else if let baseSize = entity.baseSize {
baseScale = baseSize.width / image.extent.width
}

View File

@@ -12,11 +12,11 @@ import TelegramAnimatedStickerNode
import YuvConversion
import StickerResources
private func prerenderTextTransformations(entity: DrawingTextEntity, image: UIImage, colorSpace: CGColorSpace) -> MediaEditorComposerStaticEntity {
private func prerenderTextTransformations(entity: DrawingTextEntity, image: UIImage, textScale: CGFloat, colorSpace: CGColorSpace) -> MediaEditorComposerStaticEntity {
let imageSize = image.size
let angle = -entity.rotation
let scale = entity.scale
let scale = entity.scale * 0.5 * textScale
let rotatedSize = CGSize(
width: abs(imageSize.width * cos(angle)) + abs(imageSize.height * sin(angle)),
@@ -43,10 +43,10 @@ private func prerenderTextTransformations(entity: DrawingTextEntity, image: UIIm
}
}, scale: 1.0)!
return MediaEditorComposerStaticEntity(image: CIImage(image: newImage, options: [.colorSpace: colorSpace])!, position: entity.position, scale: 1.0, rotation: 0.0, baseSize: nil, baseScale: 1.0, mirrored: false)
return MediaEditorComposerStaticEntity(image: CIImage(image: newImage, options: [.colorSpace: colorSpace])!, position: entity.position, scale: 1.0, rotation: 0.0, baseSize: nil, baseDrawingSize: CGSize(width: 1080, height: 1920), mirrored: false)
}
func composerEntitiesForDrawingEntity(account: Account, entity: DrawingEntity, colorSpace: CGColorSpace, tintColor: UIColor? = nil) -> [MediaEditorComposerEntity] {
func composerEntitiesForDrawingEntity(account: Account, textScale: CGFloat, entity: DrawingEntity, colorSpace: CGColorSpace, tintColor: UIColor? = nil) -> [MediaEditorComposerEntity] {
if let entity = entity as? DrawingStickerEntity {
let content: MediaEditorComposerStickerEntity.Content
switch entity.content {
@@ -62,19 +62,18 @@ func composerEntitiesForDrawingEntity(account: Account, entity: DrawingEntity, c
return [MediaEditorComposerStickerEntity(account: account, content: content, position: entity.position, scale: entity.scale, rotation: entity.rotation, baseSize: entity.baseSize, mirrored: entity.mirrored, colorSpace: colorSpace, tintColor: tintColor, isStatic: entity.isExplicitlyStatic)]
} else if let renderImage = entity.renderImage, let image = CIImage(image: renderImage, options: [.colorSpace: colorSpace]) {
if let entity = entity as? DrawingBubbleEntity {
return [MediaEditorComposerStaticEntity(image: image, position: entity.position, scale: 1.0, rotation: entity.rotation, baseSize: entity.size, baseScale: nil, mirrored: false)]
return [MediaEditorComposerStaticEntity(image: image, position: entity.position, scale: 1.0, rotation: entity.rotation, baseSize: entity.size, mirrored: false)]
} else if let entity = entity as? DrawingSimpleShapeEntity {
return [MediaEditorComposerStaticEntity(image: image, position: entity.position, scale: 1.0, rotation: entity.rotation, baseSize: entity.size, baseScale: nil, mirrored: false)]
return [MediaEditorComposerStaticEntity(image: image, position: entity.position, scale: 1.0, rotation: entity.rotation, baseSize: entity.size, mirrored: false)]
} else if let entity = entity as? DrawingVectorEntity {
return [MediaEditorComposerStaticEntity(image: image, position: CGPoint(x: entity.drawingSize.width * 0.5, y: entity.drawingSize.height * 0.5), scale: 1.0, rotation: 0.0, baseSize: entity.drawingSize, baseScale: nil, mirrored: false)]
return [MediaEditorComposerStaticEntity(image: image, position: CGPoint(x: entity.drawingSize.width * 0.5, y: entity.drawingSize.height * 0.5), scale: 1.0, rotation: 0.0, baseSize: entity.drawingSize, mirrored: false)]
} else if let entity = entity as? DrawingTextEntity {
var entities: [MediaEditorComposerEntity] = []
// entities.append(prerenderTextTransformations(entity: entity, image: renderImage, colorSpace: colorSpace))
entities.append(prerenderTextTransformations(entity: entity, image: renderImage, textScale: textScale, colorSpace: colorSpace))
entities.append(MediaEditorComposerStaticEntity(image: image, position: entity.position, scale: entity.scale, rotation: entity.rotation, baseSize: nil, baseScale: 0.5, mirrored: false))
if let renderSubEntities = entity.renderSubEntities {
for subEntity in renderSubEntities {
entities.append(contentsOf: composerEntitiesForDrawingEntity(account: account, entity: subEntity, colorSpace: colorSpace, tintColor: entity.color.toUIColor()))
entities.append(contentsOf: composerEntitiesForDrawingEntity(account: account, textScale: textScale, entity: subEntity, colorSpace: colorSpace, tintColor: entity.color.toUIColor()))
}
}
return entities
@@ -90,15 +89,26 @@ private class MediaEditorComposerStaticEntity: MediaEditorComposerEntity {
let rotation: CGFloat
let baseSize: CGSize?
let baseScale: CGFloat?
let baseDrawingSize: CGSize?
let mirrored: Bool
init(image: CIImage, position: CGPoint, scale: CGFloat, rotation: CGFloat, baseSize: CGSize?, baseScale: CGFloat?, mirrored: Bool) {
init(
image: CIImage,
position: CGPoint,
scale: CGFloat,
rotation: CGFloat,
baseSize: CGSize?,
baseScale: CGFloat? = nil,
baseDrawingSize: CGSize? = nil,
mirrored: Bool
) {
self.image = image
self.position = position
self.scale = scale
self.rotation = rotation
self.baseSize = baseSize
self.baseScale = baseScale
self.baseDrawingSize = baseDrawingSize
self.mirrored = mirrored
}
@@ -127,6 +137,7 @@ private class MediaEditorComposerStickerEntity: MediaEditorComposerEntity {
let rotation: CGFloat
let baseSize: CGSize?
let baseScale: CGFloat? = nil
let baseDrawingSize: CGSize? = nil
let mirrored: Bool
let colorSpace: CGColorSpace
let tintColor: UIColor?
@@ -475,6 +486,7 @@ protocol MediaEditorComposerEntity {
var rotation: CGFloat { get }
var baseSize: CGSize? { get }
var baseScale: CGFloat? { get }
var baseDrawingSize: CGSize? { get }
var mirrored: Bool { get }
func image(for time: CMTime, frameRate: Float, context: CIContext, completion: @escaping (CIImage?) -> Void)

View File

@@ -261,6 +261,7 @@ public final class MediaEditorVideoExport {
private let account: Account
private let subject: Subject
private let configuration: Configuration
private let textScale: CGFloat
private let outputPath: String
private var reader: AVAssetReader?
@@ -295,11 +296,12 @@ public final class MediaEditorVideoExport {
private let semaphore = DispatchSemaphore(value: 0)
public init(account: Account, subject: Subject, configuration: Configuration, outputPath: String) {
public init(account: Account, subject: Subject, configuration: Configuration, outputPath: String, textScale: CGFloat = 1.0) {
self.account = account
self.subject = subject
self.configuration = configuration
self.outputPath = outputPath
self.textScale = textScale
if FileManager.default.fileExists(atPath: outputPath) {
try? FileManager.default.removeItem(atPath: outputPath)
@@ -354,7 +356,7 @@ public final class MediaEditorVideoExport {
guard self.composer == nil else {
return
}
self.composer = MediaEditorComposer(account: self.account, values: self.configuration.values, dimensions: self.configuration.composerDimensions, outputDimensions: self.configuration.dimensions)
self.composer = MediaEditorComposer(account: self.account, values: self.configuration.values, dimensions: self.configuration.composerDimensions, outputDimensions: self.configuration.dimensions, textScale: self.textScale)
}
private func setupWithAsset(_ asset: AVAsset, additionalAsset: AVAsset?) {