From fd02644ca78b522fc3e7ba4a319d4cf6f131ca9f Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 15 Aug 2017 11:37:12 -0400 Subject: [PATCH 1/3] 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 From 2c3e99c3721c63cdb904ffb732fec1b875201e78 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 15 Aug 2017 15:40:46 -0400 Subject: [PATCH 2/3] better var name per code review // FREEBIE --- Signal/src/Profiles/OWSProfileManager.h | 2 +- Signal/src/Profiles/OWSProfileManager.m | 10 +++++----- Signal/src/ViewControllers/ProfileViewController.m | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Signal/src/Profiles/OWSProfileManager.h b/Signal/src/Profiles/OWSProfileManager.h index d405ca274..5d3166b88 100644 --- a/Signal/src/Profiles/OWSProfileManager.h +++ b/Signal/src/Profiles/OWSProfileManager.h @@ -9,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN extern NSString *const kNSNotificationName_LocalProfileDidChange; extern NSString *const kNSNotificationName_OtherUsersProfileDidChange; -extern const NSUInteger kOWSProfileManager_MaxAvatarWidth; +extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter; @class TSThread; @class OWSAES128Key; diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index 6b5f199fe..644883377 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -94,7 +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; +const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; @interface OWSProfileManager () @@ -403,13 +403,13 @@ const NSUInteger kOWSProfileManager_MaxAvatarWidth = 640; { NSUInteger kMaxAvatarBytes = 5 * 1000 * 1000; - if (image.size.width != kOWSProfileManager_MaxAvatarWidth - || image.size.height != kOWSProfileManager_MaxAvatarWidth) { + 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_MaxAvatarWidth, - kOWSProfileManager_MaxAvatarWidth)]; + image = [image resizedImageToFillPixelSize:CGSizeMake(kOWSProfileManager_MaxAvatarDiameter, + kOWSProfileManager_MaxAvatarDiameter)]; } NSData *_Nullable data; diff --git a/Signal/src/ViewControllers/ProfileViewController.m b/Signal/src/ViewControllers/ProfileViewController.m index 5b9c9ae51..d0b51a7b9 100644 --- a/Signal/src/ViewControllers/ProfileViewController.m +++ b/Signal/src/ViewControllers/ProfileViewController.m @@ -280,8 +280,8 @@ NS_ASSUME_NONNULL_BEGIN { OWSAssert(image); - self.avatar = [image - resizedImageToFillPixelSize:CGSizeMake(kOWSProfileManager_MaxAvatarWidth, kOWSProfileManager_MaxAvatarWidth)]; + self.avatar = [image resizedImageToFillPixelSize:CGSizeMake(kOWSProfileManager_MaxAvatarDiameter, + kOWSProfileManager_MaxAvatarDiameter)]; } - (UIViewController *)fromViewController From abec536729d7a1f2f7e816c2fb4ef79fb5973ce5 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 15 Aug 2017 16:24:33 -0400 Subject: [PATCH 3/3] simplify check for max file size per CR // FREEBIE --- Signal/src/Profiles/OWSProfileManager.m | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index 644883377..6e7b2508f 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -413,17 +413,10 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; } 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); - } + 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;