Fix sticker entities coding

This commit is contained in:
Ilya Laktyushin 2023-06-21 23:15:35 +04:00
parent e4dfc81876
commit 1639a6a7ea
5 changed files with 79 additions and 29 deletions

View File

@ -145,13 +145,13 @@ private final class CameraContext {
var ciImage = CIImage(cvImageBuffer: pixelBuffer) var ciImage = CIImage(cvImageBuffer: pixelBuffer)
let size = ciImage.extent.size let size = ciImage.extent.size
if mirror { if mirror {
var transform = CGAffineTransformMakeScale(-1.0, 1.0) var transform = CGAffineTransformMakeScale(1.0, -1.0)
transform = CGAffineTransformTranslate(transform, size.width, 0.0) transform = CGAffineTransformTranslate(transform, 0.0, -size.height)
ciImage = ciImage.transformed(by: transform) ciImage = ciImage.transformed(by: transform)
} }
ciImage = ciImage.clampedToExtent().applyingGaussianBlur(sigma: 40.0).cropped(to: CGRect(origin: .zero, size: size)) ciImage = ciImage.clampedToExtent().applyingGaussianBlur(sigma: 40.0).cropped(to: CGRect(origin: .zero, size: size))
if let cgImage = self.cameraImageContext.createCGImage(ciImage, from: ciImage.extent) { if let cgImage = self.cameraImageContext.createCGImage(ciImage, from: ciImage.extent) {
let uiImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: additional ? .up : .right) let uiImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: .right)
if additional { if additional {
CameraSimplePreviewView.saveAdditionalLastStateImage(uiImage) CameraSimplePreviewView.saveAdditionalLastStateImage(uiImage)
} else { } else {
@ -352,11 +352,11 @@ private final class CameraContext {
} else { } else {
self.configure { self.configure {
self.mainDeviceContext.invalidate() self.mainDeviceContext.invalidate()
self.mainDeviceContext = CameraDeviceContext(session: self.session, exclusive: true)
self.mainDeviceContext.configure(position: .back, previewView: self.simplePreviewView, audio: self.initialConfiguration.audio, photo: self.initialConfiguration.photo, metadata: self.initialConfiguration.metadata)
self.additionalDeviceContext?.invalidate() self.additionalDeviceContext?.invalidate()
self.additionalDeviceContext = nil self.additionalDeviceContext = nil
self.mainDeviceContext = CameraDeviceContext(session: self.session, exclusive: true)
self.mainDeviceContext.configure(position: .back, previewView: self.simplePreviewView, audio: self.initialConfiguration.audio, photo: self.initialConfiguration.photo, metadata: self.initialConfiguration.metadata)
} }
self.mainDeviceContext.output.processSampleBuffer = { [weak self] sampleBuffer, pixelBuffer, connection in self.mainDeviceContext.output.processSampleBuffer = { [weak self] sampleBuffer, pixelBuffer, connection in
guard let self else { guard let self else {

View File

@ -42,17 +42,46 @@ public class CameraSimplePreviewView: UIView {
} }
} }
private let additional: Bool
private var previewingDisposable: Disposable? private var previewingDisposable: Disposable?
private let placeholderView = UIImageView() private let placeholderView = UIImageView()
public init(frame: CGRect, additional: Bool) { public init(frame: CGRect, additional: Bool) {
self.additional = additional
super.init(frame: frame) super.init(frame: frame)
self.videoPreviewLayer.videoGravity = .resizeAspectFill self.videoPreviewLayer.videoGravity = .resizeAspectFill
self.placeholderView.alpha = 0.0
self.placeholderView.contentMode = .scaleAspectFill self.placeholderView.contentMode = .scaleAspectFill
self.placeholderView.image = additional ? CameraSimplePreviewView.lastAdditionalStateImage() : CameraSimplePreviewView.lastStateImage() self.placeholderView.image = additional ? CameraSimplePreviewView.lastAdditionalStateImage() : CameraSimplePreviewView.lastStateImage()
self.addSubview(self.placeholderView) self.addSubview(self.placeholderView)
self.resetPlaceholder()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
self.previewingDisposable?.dispose()
}
public override func layoutSubviews() {
super.layoutSubviews()
self.placeholderView.frame = self.bounds.insetBy(dx: -1.0, dy: -1.0)
}
public func resetPlaceholder() {
guard self.placeholderView.alpha == 0.0 else {
return
}
self.placeholderView.image = self.additional ? CameraSimplePreviewView.lastAdditionalStateImage() : CameraSimplePreviewView.lastStateImage()
self.placeholderView.alpha = 1.0
if #available(iOS 13.0, *) { if #available(iOS 13.0, *) {
self.previewingDisposable = (self.isPreviewing self.previewingDisposable = (self.isPreviewing
|> filter { $0 } |> filter { $0 }
@ -71,20 +100,6 @@ public class CameraSimplePreviewView: UIView {
} }
} }
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
self.previewingDisposable?.dispose()
}
public override func layoutSubviews() {
super.layoutSubviews()
self.placeholderView.frame = self.bounds.insetBy(dx: -1.0, dy: -1.0)
}
private var _videoPreviewLayer: AVCaptureVideoPreviewLayer? private var _videoPreviewLayer: AVCaptureVideoPreviewLayer?
var videoPreviewLayer: AVCaptureVideoPreviewLayer { var videoPreviewLayer: AVCaptureVideoPreviewLayer {
if let layer = self._videoPreviewLayer { if let layer = self._videoPreviewLayer {

View File

@ -1116,7 +1116,7 @@ public class CameraScreen: ViewController {
let previousPosition = self.cameraPosition let previousPosition = self.cameraPosition
self.cameraPosition = state.position self.cameraPosition = state.position
self.isDualCamEnabled = state.isDualCamEnabled self.isDualCamEnabled = state.isDualCamEnabled
if self.isDualCamEnabled && previousPosition != state.position, let additionalPreviewView = self.additionalPreviewView { if self.isDualCamEnabled && previousPosition != state.position, let additionalPreviewView = self.additionalPreviewView {
if state.position == .front { if state.position == .front {
additionalPreviewView.superview?.sendSubviewToBack(additionalPreviewView) additionalPreviewView.superview?.sendSubviewToBack(additionalPreviewView)
@ -1600,7 +1600,7 @@ public class CameraScreen: ViewController {
transition.setFrame(view: self.previewBlurView, frame: CGRect(origin: .zero, size: previewFrame.size)) transition.setFrame(view: self.previewBlurView, frame: CGRect(origin: .zero, size: previewFrame.size))
if let additionalPreviewView = self.currentAdditionalPreviewView { if let additionalPreviewView = self.currentAdditionalPreviewView as? CameraSimplePreviewView {
additionalPreviewView.layer.cornerRadius = 80.0 additionalPreviewView.layer.cornerRadius = 80.0
var origin: CGPoint var origin: CGPoint
@ -1632,7 +1632,11 @@ public class CameraScreen: ViewController {
} }
let additionalPreviewFrame = CGRect(origin: origin, size: CGSize(width: 160.0, height: 160.0)) let additionalPreviewFrame = CGRect(origin: origin, size: CGSize(width: 160.0, height: 160.0))
transition.setPosition(view: additionalPreviewView, position: additionalPreviewFrame.center) transition.setPosition(view: additionalPreviewView, position: additionalPreviewFrame.center, completion: { _ in
if !self.isDualCamEnabled {
additionalPreviewView.resetPlaceholder()
}
})
transition.setBounds(view: additionalPreviewView, bounds: CGRect(origin: .zero, size: additionalPreviewFrame.size)) transition.setBounds(view: additionalPreviewView, bounds: CGRect(origin: .zero, size: additionalPreviewFrame.size))
transition.setScale(view: additionalPreviewView, scale: self.isDualCamEnabled ? 1.0 : 0.1) transition.setScale(view: additionalPreviewView, scale: self.isDualCamEnabled ? 1.0 : 0.1)

View File

@ -4,6 +4,14 @@ import Display
import AccountContext import AccountContext
import TelegramCore import TelegramCore
private func entitiesPath() -> String {
return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/mediaEntities"
}
private func fullEntityMediaPath(_ path: String) -> String {
return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/mediaEntities/" + path
}
public final class DrawingStickerEntity: DrawingEntity, Codable { public final class DrawingStickerEntity: DrawingEntity, Codable {
public enum Content: Equatable { public enum Content: Equatable {
case file(TelegramMediaFile) case file(TelegramMediaFile)
@ -36,9 +44,9 @@ public final class DrawingStickerEntity: DrawingEntity, Codable {
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case uuid case uuid
case file case file
case image case imagePath
case videoPath case videoPath
case videoImage case videoImagePath
case referenceDrawingSize case referenceDrawingSize
case position case position
case scale case scale
@ -101,11 +109,11 @@ public final class DrawingStickerEntity: DrawingEntity, Codable {
self.uuid = try container.decode(UUID.self, forKey: .uuid) self.uuid = try container.decode(UUID.self, forKey: .uuid)
if let file = try container.decodeIfPresent(TelegramMediaFile.self, forKey: .file) { if let file = try container.decodeIfPresent(TelegramMediaFile.self, forKey: .file) {
self.content = .file(file) self.content = .file(file)
} else if let imageData = try container.decodeIfPresent(Data.self, forKey: .image), let image = UIImage(data: imageData) { } else if let imagePath = try container.decodeIfPresent(String.self, forKey: .imagePath), let image = UIImage(contentsOfFile: fullEntityMediaPath(imagePath)) {
self.content = .image(image) self.content = .image(image)
} else if let videoPath = try container.decodeIfPresent(String.self, forKey: .videoPath) { } else if let videoPath = try container.decodeIfPresent(String.self, forKey: .videoPath) {
var imageValue: UIImage? var imageValue: UIImage?
if let imageData = try container.decodeIfPresent(Data.self, forKey: .image), let image = UIImage(data: imageData) { if let imagePath = try container.decodeIfPresent(String.self, forKey: .videoImagePath), let image = UIImage(contentsOfFile: fullEntityMediaPath(imagePath)) {
imageValue = image imageValue = image
} }
self.content = .video(videoPath, imageValue) self.content = .video(videoPath, imageValue)
@ -126,10 +134,22 @@ public final class DrawingStickerEntity: DrawingEntity, Codable {
case let .file(file): case let .file(file):
try container.encode(file, forKey: .file) try container.encode(file, forKey: .file)
case let .image(image): case let .image(image):
try container.encodeIfPresent(image.pngData(), forKey: .image) let imagePath = "\(self.uuid).png"
let fullImagePath = fullEntityMediaPath(imagePath)
if let imageData = image.pngData() {
try? FileManager.default.createDirectory(atPath: entitiesPath(), withIntermediateDirectories: true)
try? imageData.write(to: URL(fileURLWithPath: fullImagePath))
try container.encodeIfPresent(imagePath, forKey: .imagePath)
}
case let .video(path, image): case let .video(path, image):
try container.encode(path, forKey: .videoPath) try container.encode(path, forKey: .videoPath)
try container.encodeIfPresent(image?.jpegData(compressionQuality: 0.87), forKey: .videoImage) let imagePath = "\(self.uuid).jpg"
let fullImagePath = fullEntityMediaPath(imagePath)
if let imageData = image?.jpegData(compressionQuality: 0.87) {
try? FileManager.default.createDirectory(atPath: entitiesPath(), withIntermediateDirectories: true)
try? imageData.write(to: URL(fileURLWithPath: fullImagePath))
try container.encodeIfPresent(imagePath, forKey: .videoImagePath)
}
} }
try container.encode(self.referenceDrawingSize, forKey: .referenceDrawingSize) try container.encode(self.referenceDrawingSize, forKey: .referenceDrawingSize)
try container.encode(self.position, forKey: .position) try container.encode(self.position, forKey: .position)

View File

@ -3667,6 +3667,17 @@ final class PrivacyButtonComponent: CombinedComponent {
context.add(text context.add(text
.position(CGPoint(x: backgroundSize.width / 2.0 + 7.0, y: backgroundSize.height / 2.0)) .position(CGPoint(x: backgroundSize.width / 2.0 + 7.0, y: backgroundSize.height / 2.0))
.update(Transition.Update { _, view, _ in
if let snapshot = view.snapshotView(afterScreenUpdates: false) {
let transition = Transition(animation: .curve(duration: 0.2, curve: .easeInOut))
view.superview?.addSubview(snapshot)
transition.setAlpha(view: snapshot, alpha: 0.0, completion: { [weak snapshot] _ in
snapshot?.removeFromSuperview()
})
snapshot.frame = view.frame
transition.animateAlpha(view: view, from: 0.0, to: 1.0)
}
})
) )
return backgroundSize return backgroundSize