diff --git a/Signal/src/ViewControllers/GroupViewHelper.m b/Signal/src/ViewControllers/GroupViewHelper.m index 60a689928..d980e1f70 100644 --- a/Signal/src/ViewControllers/GroupViewHelper.m +++ b/Signal/src/ViewControllers/GroupViewHelper.m @@ -115,8 +115,10 @@ NS_ASSUME_NONNULL_BEGIN UIImage *rawAvatar = [info objectForKey:UIImagePickerControllerOriginalImage]; if (rawAvatar) { - // TODO: There may be a bug here. - UIImage *resizedAvatar = [rawAvatar resizedImageToFitInSize:CGSizeMake(100.00, 100.00) scaleIfSmaller:NO]; + // We resize the avatar to fill a 210x210 square. + // + // See: GroupCreateActivity.java in Signal-Android.java. + UIImage *resizedAvatar = [rawAvatar resizedImageToFillPixelSize:CGSizeMake(210, 210)]; [self.delegate groupAvatarDidChange:resizedAvatar]; } diff --git a/Signal/src/util/UIImage+normalizeImage.h b/Signal/src/util/UIImage+normalizeImage.h index 67068fc50..5a9f601f8 100644 --- a/Signal/src/util/UIImage+normalizeImage.h +++ b/Signal/src/util/UIImage+normalizeImage.h @@ -1,9 +1,5 @@ // -// UIImage+normalizeImage.h -// Signal -// -// Created by Frederic Jacobs on 26/12/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // #import @@ -14,6 +10,6 @@ - (UIImage *)resizedWithQuality:(CGInterpolationQuality)quality rate:(CGFloat)rate; - (UIImage *)resizedImageToSize:(CGSize)dstSize; -- (UIImage *)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale; +- (UIImage *)resizedImageToFillPixelSize:(CGSize)boundingSize; @end diff --git a/Signal/src/util/UIImage+normalizeImage.m b/Signal/src/util/UIImage+normalizeImage.m index 6c80a48c2..ceb12524e 100644 --- a/Signal/src/util/UIImage+normalizeImage.m +++ b/Signal/src/util/UIImage+normalizeImage.m @@ -1,9 +1,5 @@ // -// UIImage+normalizeImage.m -// Signal -// -// Created by Frederic Jacobs on 26/12/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // #import "UIImage+normalizeImage.h" @@ -11,8 +7,9 @@ @implementation UIImage (normalizeImage) - (UIImage *)normalizedImage { - if (self.imageOrientation == UIImageOrientationUp) + if (self.imageOrientation == UIImageOrientationUp) { return self; + } UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); [self drawInRect:(CGRect){{0, 0}, self.size}]; @@ -21,7 +18,6 @@ return normalizedImage; } - - (UIImage *)resizedWithQuality:(CGInterpolationQuality)quality rate:(CGFloat)rate { UIImage *resized = nil; CGFloat width = self.size.width * rate; @@ -132,49 +128,42 @@ return resizedImage; } -- (UIImage *)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale { - // get the image size (independant of imageOrientation) - CGImageRef imgRef = self.CGImage; - CGSize srcSize = - CGSizeMake(CGImageGetWidth(imgRef), - CGImageGetHeight(imgRef)); // not equivalent to self.size (which depends on the imageOrientation)! - - // adjust boundingSize to make it independant on imageOrientation too for farther computations - UIImageOrientation orient = self.imageOrientation; - switch (orient) { - case UIImageOrientationLeft: - case UIImageOrientationRight: - case UIImageOrientationLeftMirrored: - case UIImageOrientationRightMirrored: - boundingSize = CGSizeMake(boundingSize.height, boundingSize.width); - break; - default: - // NOP - break; - } - - // Compute the target CGRect in order to keep aspect-ratio - CGSize dstSize; - - if (!scale && (srcSize.width < boundingSize.width) && (srcSize.height < boundingSize.height)) { - // NSLog(@"Image is smaller, and we asked not to scale it in this case (scaleIfSmaller:NO)"); - dstSize = srcSize; // no resize (we could directly return 'self' here, but we draw the image anyway to take - // image orientation into account) +- (UIImage *)resizedImageToFillPixelSize:(CGSize)dstSize +{ + OWSAssert(dstSize.width > 0); + OWSAssert(dstSize.height > 0); + + UIImage *normalized = [self normalizedImage]; + + // Get the size in pixels, not points. + CGSize srcSize = CGSizeMake(CGImageGetWidth(normalized.CGImage), CGImageGetHeight(normalized.CGImage)); + OWSAssert(srcSize.width > 0); + OWSAssert(srcSize.height > 0); + + CGFloat widthRatio = srcSize.width / dstSize.width; + CGFloat heightRatio = srcSize.height / dstSize.height; + CGRect drawRect = CGRectZero; + if (widthRatio > heightRatio) { + drawRect.origin.y = 0; + drawRect.size.height = dstSize.height; + drawRect.size.width = dstSize.height * srcSize.width / srcSize.height; + OWSAssert(drawRect.size.width > dstSize.width); + drawRect.origin.x = (drawRect.size.width - dstSize.width) * -0.5f; } else { - CGFloat wRatio = boundingSize.width / srcSize.width; - CGFloat hRatio = boundingSize.height / srcSize.height; - - if (wRatio < hRatio) { - // NSLog(@"Width imposed, Height scaled ; ratio = %f",wRatio); - dstSize = CGSizeMake(boundingSize.width, (CGFloat)floor(srcSize.height * wRatio)); - } else { - // NSLog(@"Height imposed, Width scaled ; ratio = %f",hRatio); - dstSize = CGSizeMake((CGFloat)floor(srcSize.width * hRatio), boundingSize.height); - } + drawRect.origin.x = 0; + drawRect.size.width = dstSize.width; + drawRect.size.height = dstSize.width * srcSize.height / srcSize.width; + OWSAssert(drawRect.size.height > dstSize.height); + drawRect.origin.y = (drawRect.size.height - dstSize.height) * -0.5f; } - return [self resizedImageToSize:dstSize]; + UIGraphicsBeginImageContextWithOptions(dstSize, NO, 1.f); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSetInterpolationQuality(context, kCGInterpolationHigh); + [self drawInRect:drawRect]; + UIImage *dstImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return dstImage; } - @end