diff --git a/Signal/src/Profiles/OWSProfileManager.h b/Signal/src/Profiles/OWSProfileManager.h index 558d596fa..5d3166b88 100644 --- a/Signal/src/Profiles/OWSProfileManager.h +++ b/Signal/src/Profiles/OWSProfileManager.h @@ -9,6 +9,8 @@ NS_ASSUME_NONNULL_BEGIN extern NSString *const kNSNotificationName_LocalProfileDidChange; extern NSString *const kNSNotificationName_OtherUsersProfileDidChange; +extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter; + @class TSThread; @class OWSAES128Key; diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index d4e560fa1..6e7b2508f 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -94,6 +94,7 @@ NSString *const kOWSProfileManager_GroupWhitelistCollection = @"kOWSProfileManag /// The max bytes for a user's profile name, encoded in UTF8. /// Before encrypting and submitting we NULL pad the name data to this length. static const NSUInteger kOWSProfileManager_NameDataLength = 26; +const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; @interface OWSProfileManager () @@ -381,7 +382,7 @@ static const NSUInteger kOWSProfileManager_NameDataLength = 26; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (avatar) { - NSData *_Nullable data = UIImageJPEGRepresentation(avatar, 1.f); + NSData *data = [self processedImageDataForRawAvatar:avatar]; OWSAssert(data); if (data) { NSString *fileName = [[NSUUID UUID].UUIDString stringByAppendingPathExtension:@"jpg"]; @@ -398,6 +399,29 @@ static const NSUInteger kOWSProfileManager_NameDataLength = 26; }); } +- (NSData *)processedImageDataForRawAvatar:(UIImage *)image +{ + NSUInteger kMaxAvatarBytes = 5 * 1000 * 1000; + + if (image.size.width != kOWSProfileManager_MaxAvatarDiameter + || image.size.height != kOWSProfileManager_MaxAvatarDiameter) { + // To help ensure the user is being shown the same cropping of their avatar as + // everyone else will see, we want to be sure that the image was resized before this point. + OWSFail(@"Avatar image should have been resized before trying to upload"); + image = [image resizedImageToFillPixelSize:CGSizeMake(kOWSProfileManager_MaxAvatarDiameter, + kOWSProfileManager_MaxAvatarDiameter)]; + } + + NSData *_Nullable data; + if (data.length > kMaxAvatarBytes) { + // Our avatar dimensions are so small that it's incredibly unlikely we wouldn't be able to fit our profile + // photo. e.g. generating pure noise at our resolution compresses to ~200k. + OWSFail(@"Suprised to find profile avatar was too large. Was it scaled properly? image: %@", image); + } + + return data; +} + - (void)uploadAvatarToService:(NSData *)avatarData success:(void (^)(NSString *avatarUrlPath))successBlock failure:(void (^)())failureBlock diff --git a/Signal/src/ViewControllers/ProfileViewController.m b/Signal/src/ViewControllers/ProfileViewController.m index 45094027c..d0b51a7b9 100644 --- a/Signal/src/ViewControllers/ProfileViewController.m +++ b/Signal/src/ViewControllers/ProfileViewController.m @@ -280,9 +280,8 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(image); - // TODO: Crop to square and possible resize. - - self.avatar = image; + self.avatar = [image resizedImageToFillPixelSize:CGSizeMake(kOWSProfileManager_MaxAvatarDiameter, + kOWSProfileManager_MaxAvatarDiameter)]; } - (UIViewController *)fromViewController