From fd02644ca78b522fc3e7ba4a319d4cf6f131ca9f Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 15 Aug 2017 11:37:12 -0400 Subject: [PATCH] resize profile avatar // FREEBIE --- Signal/src/Profiles/OWSProfileManager.h | 2 ++ Signal/src/Profiles/OWSProfileManager.m | 33 ++++++++++++++++++- .../ViewControllers/ProfileViewController.m | 5 ++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/Signal/src/Profiles/OWSProfileManager.h b/Signal/src/Profiles/OWSProfileManager.h index 558d596fa..d405ca274 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_MaxAvatarWidth; + @class TSThread; @class OWSAES128Key; diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index d4e560fa1..6b5f199fe 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_MaxAvatarWidth = 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,36 @@ static const NSUInteger kOWSProfileManager_NameDataLength = 26; }); } +- (NSData *)processedImageDataForRawAvatar:(UIImage *)image +{ + NSUInteger kMaxAvatarBytes = 5 * 1000 * 1000; + + if (image.size.width != kOWSProfileManager_MaxAvatarWidth + || image.size.height != kOWSProfileManager_MaxAvatarWidth) { + // 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_MaxAvatarWidth, + kOWSProfileManager_MaxAvatarWidth)]; + } + + NSData *_Nullable data; + for (NSUInteger attempts = 0; attempts < 5; attempts++) { + CGFloat quality = (CGFloat)0.95 - attempts * (CGFloat)0.1; + data = UIImageJPEGRepresentation(image, quality); + if (data.length <= kMaxAvatarBytes) { + return data; + } else { + // This for-loop is really just paranoia. Our avatar dimensions are so small that + // it's incredibly unlikely we wouldn't be able to fit our profile photo with even + // our highest quality. + 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..5b9c9ae51 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_MaxAvatarWidth, kOWSProfileManager_MaxAvatarWidth)]; } - (UIViewController *)fromViewController