diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryPhotoItemView.m b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryPhotoItemView.m index fa6bb67318..7a2e3403c7 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryPhotoItemView.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryPhotoItemView.m @@ -23,8 +23,12 @@ #import +#import "TGPaintFaceDetector.h" + @interface TGMediaPickerGalleryPhotoItemView () { + SMetaDisposable *_facesDisposable; + UILabel *_fileInfoLabel; TGMessageImageViewOverlayView *_progressView; @@ -57,6 +61,8 @@ self = [super initWithFrame:frame]; if (self != nil) { + _facesDisposable = [[SMetaDisposable alloc] init]; + __weak TGMediaPickerGalleryPhotoItemView *weakSelf = self; _imageView = [[TGModernGalleryImageItemImageView alloc] init]; _imageView.clipsToBounds = true; @@ -101,6 +107,7 @@ { [_adjustmentsDisposable dispose]; [_attributesDisposable dispose]; + [_facesDisposable dispose]; } - (void)setHiddenAsBeingEdited:(bool)hidden @@ -226,8 +233,11 @@ }]]; - if (!item.asFile) + if (!item.asFile) { + [_facesDisposable setDisposable:[[TGPaintFaceDetector detectFacesInItem:item.editableMediaItem editingContext:item.editingContext] startWithNext:nil]]; + return; + } _fileInfoLabel.text = nil; diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m index e221f89126..7f8e0c90a0 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryVideoItemView.m @@ -41,6 +41,7 @@ #import #import "PGPhotoEditor.h" +#import "TGPaintFaceDetector.h" @interface TGMediaPickerGalleryVideoItemView() { @@ -96,6 +97,7 @@ SMetaDisposable *_adjustmentsDisposable; SMetaDisposable *_attributesDisposable; SMetaDisposable *_downloadDisposable; + SMetaDisposable *_facesDisposable; SMetaDisposable *_currentAudioSession; SVariable *_editableItemVariable; @@ -131,6 +133,7 @@ _currentAudioSession = [[SMetaDisposable alloc] init]; _playerItemDisposable = [[SMetaDisposable alloc] init]; + _facesDisposable = [[SMetaDisposable alloc] init]; _videoDurationVar = [[SVariable alloc] init]; _videoDurationDisposable = [[SMetaDisposable alloc] init]; @@ -251,6 +254,7 @@ [_thumbnailsDisposable dispose]; [_attributesDisposable dispose]; [_downloadDisposable dispose]; + [_facesDisposable dispose]; [self stopPlayer]; [self releaseVolumeOverlay]; @@ -385,8 +389,13 @@ [super setItem:item synchronously:synchronously]; - if (itemChanged) + if (itemChanged) { [self _playerCleanup]; + + if (!item.asFile) { + [_facesDisposable setDisposable:[[TGPaintFaceDetector detectFacesInItem:item.editableMediaItem editingContext:item.editingContext] startWithNext:nil]]; + } + } _scrubberView.allowsTrimming = false; _videoDimensions = item.dimensions; diff --git a/submodules/LegacyComponents/Sources/TGPaintFaceDetector.h b/submodules/LegacyComponents/Sources/TGPaintFaceDetector.h index c12151e06d..c08915ac85 100644 --- a/submodules/LegacyComponents/Sources/TGPaintFaceDetector.h +++ b/submodules/LegacyComponents/Sources/TGPaintFaceDetector.h @@ -1,6 +1,9 @@ #import #import +@protocol TGMediaEditableItem; +@class TGMediaEditingContext; + @interface TGPaintFaceFeature : NSObject { CGPoint _position; @@ -49,6 +52,8 @@ + (SSignal *)detectFacesInImage:(UIImage *)image originalSize:(CGSize)originalSize; ++ (SSignal *)detectFacesInItem:(id)item editingContext:(TGMediaEditingContext *)editingContext; + @end diff --git a/submodules/LegacyComponents/Sources/TGPaintFaceDetector.m b/submodules/LegacyComponents/Sources/TGPaintFaceDetector.m index 05646d1490..3933ca631b 100644 --- a/submodules/LegacyComponents/Sources/TGPaintFaceDetector.m +++ b/submodules/LegacyComponents/Sources/TGPaintFaceDetector.m @@ -3,6 +3,8 @@ #import #import +#import "TGMediaEditingContext.m" + @interface TGPaintFace () + (instancetype)faceWithBounds:(CGRect)bounds angle:(CGFloat)angle leftEye:(TGPaintFaceEye *)leftEye rightEye:(TGPaintFaceEye *)rightEye mouth:(TGPaintFaceMouth *)mouth; @@ -26,6 +28,41 @@ @implementation TGPaintFaceDetector ++ (SSignal *)detectFacesInItem:(id)item editingContext:(TGMediaEditingContext *)editingContext +{ + CGSize originalSize = item.originalSize; + + SSignal *cachedFaces = [editingContext facesForItem:item]; + SSignal *cachedSignal = [cachedFaces mapToSignal:^SSignal *(id result) + { + if (result == nil) + return [SSignal fail:nil]; + return [SSignal single:result]; + }]; + + SSignal *imageSignal = [item screenImageSignal:0]; + SSignal *detectSignal = [[[imageSignal filter:^bool(UIImage *image) + { + if (![image isKindOfClass:[UIImage class]]) + return false; + + if (image.degraded) + return false; + + return true; + }] take:1] mapToSignal:^SSignal *(UIImage *image) { + return [[TGPaintFaceDetector detectFacesInImage:image originalSize:originalSize] startOn:[SQueue concurrentDefaultQueue]]; + }]; + + return [[[cachedSignal catch:^SSignal *(__unused id error) + { + return detectSignal; + }] deliverOn:[SQueue mainQueue]] onNext:^(NSArray *next) + { + [editingContext setFaces:next forItem:item]; + }]; +} + + (SSignal *)detectFacesInImage:(UIImage *)image originalSize:(CGSize)originalSize { return [[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) diff --git a/submodules/LegacyComponents/Sources/TGPhotoAvatarPreviewController.m b/submodules/LegacyComponents/Sources/TGPhotoAvatarPreviewController.m index 1836cb7e2b..7bc3e8c7c1 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoAvatarPreviewController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoAvatarPreviewController.m @@ -263,7 +263,9 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel - (void)prepareTransitionInWithReferenceView:(UIView *)referenceView referenceFrame:(CGRect)referenceFrame parentView:(UIView *)parentView noTransitionView:(bool)noTransitionView { [super prepareTransitionInWithReferenceView:referenceView referenceFrame:referenceFrame parentView:parentView noTransitionView:noTransitionView]; - [self.view insertSubview:_transitionView belowSubview:_wrapperView]; + + if (self.initialAppearance && self.fromCamera) + [self.view insertSubview:_transitionView belowSubview:_wrapperView]; } - (void)transitionIn