From f041a7df2ec8d7db804cd6ec3f401c13dc389951 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 16 Jul 2020 17:07:16 +0300 Subject: [PATCH] Video avatar fixes --- .../LegacyComponents/TGVideoEditAdjustments.h | 2 +- .../Sources/TGAttachmentCarouselItemView.m | 32 +++++++++- .../Sources/TGCameraController.m | 2 +- .../Sources/TGMediaAssetsController.m | 2 +- .../Sources/TGMediaAssetsPickerController.m | 29 ++++++++- .../Sources/TGPhotoEditorController.m | 7 ++- .../Sources/TGPhotoPaintController.m | 6 +- .../Sources/TGVideoEditAdjustments.m | 4 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 61 ------------------- .../Sources/LegacyWebSearchGallery.swift | 2 +- 10 files changed, 71 insertions(+), 76 deletions(-) diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h index 0c426975f8..32dcbcc3a9 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGVideoEditAdjustments.h @@ -37,7 +37,7 @@ typedef enum - (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset maxDuration:(NSTimeInterval)maxDuration; - (instancetype)editAdjustmentsWithPreset:(TGMediaVideoConversionPreset)preset videoStartValue:(NSTimeInterval)videoStartValue trimStartValue:(NSTimeInterval)trimStartValue trimEndValue:(NSTimeInterval)trimEndValue; + (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize preset:(TGMediaVideoConversionPreset)preset; -+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values; ++ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values preset:(TGMediaVideoConversionPreset)preset; + (instancetype)editAdjustmentsWithDictionary:(NSDictionary *)dictionary; + (instancetype)editAdjustmentsWithOriginalSize:(CGSize)originalSize diff --git a/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m b/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m index d1f45ee224..37da1a71a1 100644 --- a/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m +++ b/submodules/LegacyComponents/Sources/TGAttachmentCarouselItemView.m @@ -898,7 +898,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500; }; __weak TGPhotoEditorController *weakController = controller; - controller.didFinishEditing = ^(__unused id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges) + controller.didFinishEditing = ^(id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges) { if (!hasChanges) return; @@ -911,8 +911,34 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500; if (strongController == nil) return; - if (strongSelf.avatarCompletionBlock != nil) - strongSelf.avatarCompletionBlock(resultImage); + if (adjustments.paintingData.hasAnimation) { + TGVideoEditAdjustments *videoAdjustments = adjustments; + if ([videoAdjustments isKindOfClass:[PGPhotoEditorValues class]]) { + videoAdjustments = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetProfileVeryHigh]; + } + + NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"gifvideo_%x.jpg", (int)arc4random()]]; + NSData *data = UIImageJPEGRepresentation(resultImage, 0.8); + [data writeToFile:filePath atomically:true]; + + UIImage *previewImage = resultImage; + if ([adjustments cropAppliedForAvatar:false] || adjustments.hasPainting || adjustments.toolsApplied) + { + UIImage *paintingImage = adjustments.paintingData.stillImage; + if (paintingImage == nil) { + paintingImage = adjustments.paintingData.image; + } + UIImage *thumbnailImage = TGPhotoEditorVideoExtCrop(resultImage, paintingImage, adjustments.cropOrientation, adjustments.cropRotation, adjustments.cropRect, adjustments.cropMirrored, TGScaleToFill(asset.dimensions, CGSizeMake(800, 800)), adjustments.originalSize, true, true, true); + if (thumbnailImage != nil) { + previewImage = thumbnailImage; + } + } + if (strongSelf.avatarVideoCompletionBlock != nil) + strongSelf.avatarVideoCompletionBlock(previewImage, [NSURL fileURLWithPath:filePath], videoAdjustments); + } else { + if (strongSelf.avatarCompletionBlock != nil) + strongSelf.avatarCompletionBlock(resultImage); + } }; controller.didFinishEditingVideo = ^(AVAsset *asset, id adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) { if (!hasChanges) diff --git a/submodules/LegacyComponents/Sources/TGCameraController.m b/submodules/LegacyComponents/Sources/TGCameraController.m index 8a7e0e8f45..638153c61f 100644 --- a/submodules/LegacyComponents/Sources/TGCameraController.m +++ b/submodules/LegacyComponents/Sources/TGCameraController.m @@ -2592,7 +2592,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus if (animated) { dict[@"isAnimation"] = @true; if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) { - dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments]; + dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetAnimation]; } else { dict[@"adjustments"] = adjustments; } diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m index 87202ef3e0..7c295a7652 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m @@ -904,7 +904,7 @@ if (animated) { dict[@"isAnimation"] = @true; if ([adjustments isKindOfClass:[PGPhotoEditorValues class]]) { - dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments]; + dict[@"adjustments"] = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetAnimation]; } else { dict[@"adjustments"] = adjustments; } diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m b/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m index 2408a9916d..f885339c4e 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsPickerController.m @@ -415,7 +415,7 @@ [[strongSelf->_assetsLibrary saveAssetWithImage:resultImage] startWithNext:nil]; }; - controller.didFinishEditing = ^(__unused id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges) + controller.didFinishEditing = ^(id adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, bool hasChanges) { if (!hasChanges) return; @@ -424,7 +424,32 @@ if (strongSelf == nil) return; - [(TGMediaAssetsController *)strongSelf.navigationController completeWithAvatarImage:resultImage]; + if (adjustments.paintingData.hasAnimation) { + TGVideoEditAdjustments *videoAdjustments = adjustments; + if ([videoAdjustments isKindOfClass:[PGPhotoEditorValues class]]) { + videoAdjustments = [TGVideoEditAdjustments editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)adjustments preset:TGMediaVideoConversionPresetProfileVeryHigh]; + } + + NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"gifvideo_%x.jpg", (int)arc4random()]]; + NSData *data = UIImageJPEGRepresentation(resultImage, 0.8); + [data writeToFile:filePath atomically:true]; + + UIImage *previewImage = resultImage; + if ([adjustments cropAppliedForAvatar:false] || adjustments.hasPainting || adjustments.toolsApplied) + { + UIImage *paintingImage = adjustments.paintingData.stillImage; + if (paintingImage == nil) { + paintingImage = adjustments.paintingData.image; + } + UIImage *thumbnailImage = TGPhotoEditorVideoExtCrop(resultImage, paintingImage, adjustments.cropOrientation, adjustments.cropRotation, adjustments.cropRect, adjustments.cropMirrored, TGScaleToFill(asset.dimensions, CGSizeMake(800, 800)), adjustments.originalSize, true, true, true); + if (thumbnailImage != nil) { + previewImage = thumbnailImage; + } + } + [(TGMediaAssetsController *)strongSelf.navigationController completeWithAvatarVideo:[NSURL fileURLWithPath:filePath] adjustments:videoAdjustments image:previewImage]; + } else { + [(TGMediaAssetsController *)strongSelf.navigationController completeWithAvatarImage:resultImage]; + } }; controller.didFinishEditingVideo = ^(AVAsset *asset, id adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) { if (!hasChanges) diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m index 5ab940f53d..52a42133d0 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m @@ -1061,8 +1061,13 @@ UIImage *image = result[@"image"]; UIImage *thumbnailImage = result[@"thumbnail"]; - if (avatar && completion != nil) + if (avatar && image.size.width < 150.0) { + image = TGScaleImageToPixelSize(image, CGSizeMake(150.0, 150.0)); + } + + if (avatar && completion != nil) { completion(image); + } if (!saveOnly && didFinishEditing != nil) didFinishEditing(editorValues, image, thumbnailImage, true); diff --git a/submodules/LegacyComponents/Sources/TGPhotoPaintController.m b/submodules/LegacyComponents/Sources/TGPhotoPaintController.m index 8ea03393d0..05fc3583a3 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoPaintController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoPaintController.m @@ -1900,6 +1900,8 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f; - (void)transitionOutSwitching:(bool)__unused switching completion:(void (^)(void))completion { + [_stickersScreen invalidate]; + TGPhotoEditorPreviewView *previewView = self.previewView; previewView.interactionEnded = nil; @@ -1931,9 +1933,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f; - (void)_animatePreviewViewTransitionOutToFrame:(CGRect)targetFrame saving:(bool)saving parentView:(UIView *)parentView completion:(void (^)(void))completion { _dismissing = true; - - [_stickersScreen invalidate]; - + [_entitySelectionView removeFromSuperview]; _entitySelectionView = nil; diff --git a/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m b/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m index abd845c063..f6b96bb53d 100644 --- a/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m +++ b/submodules/LegacyComponents/Sources/TGVideoEditAdjustments.m @@ -136,7 +136,7 @@ const NSTimeInterval TGVideoEditMaximumGifDuration = 30.5; return adjustments; } -+ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values { ++ (instancetype)editAdjustmentsWithPhotoEditorValues:(PGPhotoEditorValues *)values preset:(TGMediaVideoConversionPreset)preset { TGVideoEditAdjustments *adjustments = [[[self class] alloc] init]; adjustments->_originalSize = values.originalSize; CGRect cropRect = values.cropRect; @@ -150,7 +150,7 @@ const NSTimeInterval TGVideoEditMaximumGifDuration = 30.5; adjustments->_cropMirrored = values.cropMirrored; adjustments->_paintingData = [values.paintingData dataForAnimation]; adjustments->_sendAsGif = true; - adjustments->_preset = TGMediaVideoConversionPresetAnimation; + adjustments->_preset = preset; return adjustments; } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 5d590a8832..107878889b 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -3846,68 +3846,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } } } - - private func editAvatarItem(_ item: PeerInfoAvatarListItem) { - guard case let .image(reference, representations, videoRepresentations, _) = item else { - return - } - let mediaReference: AnyMediaReference - if let video = videoRepresentations.last { - mediaReference = .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.representation.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.representation.dimensions, flags: [])])) - } else { - let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) - mediaReference = .standalone(media: media) - } - - var dismissStatus: (() -> Void)? - let statusController = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: { - dismissStatus?() - })) - dismissStatus = { [weak self, weak statusController] in - self?.editAvatarDisposable.set(nil) - statusController?.dismiss() - } - self.controller?.present(statusController, in: .window(.root)) - - self.editAvatarDisposable.set((fetchMediaData(context: self.context, postbox: self.context.account.postbox, mediaReference: mediaReference) - |> deliverOnMainQueue).start(next: { [weak self] state, isImage in - guard let strongSelf = self else { - return - } - switch state { - case .progress: - break - case let .data(data): - dismissStatus?() - - let image: UIImage? - let video: URL? - if isImage { - if let fileData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) { - image = UIImage(data: fileData) - } else { - image = nil - } - video = nil - } else { - image = nil - video = URL(fileURLWithPath: data.path) - } - -// presentLegacyAvatarEditor(theme: strongSelf.presentationData.theme, image: image, video: video, present: { [weak self] c, a in -// if let strongSelf = self { -// strongSelf.controller?.present(c, in: .window(.root), with: a, blockInteraction: true) -// } -// }, imageCompletion: { [weak self] image in -// self?.updateProfilePhoto(image) -// }, videoCompletion: { [weak self] image, url, adjustments in -// self?.updateProfileVideo(image, url: url, adjustments: adjustments) -// }) - } - })) - } - private func setMainAvatar(_ item: PeerInfoAvatarListItem) { if self.data?.peer?.id == self.context.account.peerId { if case let .image(reference, _, _, _) = item { diff --git a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift index dbf1098e8f..99e7fab29a 100644 --- a/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift +++ b/submodules/WebSearchUI/Sources/LegacyWebSearchGallery.swift @@ -443,7 +443,7 @@ public func legacyEnqueueWebSearchMessages(_ selectionState: TGMediaSelectionCon if animated { dict["isAnimation"] = true if let photoEditorValues = adjustments as? PGPhotoEditorValues { - dict["adjustments"] = TGVideoEditAdjustments(photoEditorValues: photoEditorValues) + dict["adjustments"] = TGVideoEditAdjustments(photoEditorValues: photoEditorValues, preset: TGMediaVideoConversionPresetAnimation) } let filePath = NSTemporaryDirectory().appending("/gifvideo_\(arc4random()).jpg")