From 51d1b50ef4b396dfa45183bdd1fb21fd8905dea3 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Tue, 15 Mar 2022 17:54:44 +0800 Subject: [PATCH] Fix the false decode implementation using the ImageRenderer instead of directly create CGContext --- SDWebImage/Core/SDImageCoderHelper.m | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/SDWebImage/Core/SDImageCoderHelper.m b/SDWebImage/Core/SDImageCoderHelper.m index eb5116ba..8b305441 100644 --- a/SDWebImage/Core/SDImageCoderHelper.m +++ b/SDWebImage/Core/SDImageCoderHelper.m @@ -15,6 +15,7 @@ #import "SDAssociatedObject.h" #import "UIImage+Metadata.h" #import "SDInternalMacros.h" +#import "SDGraphicsImageRenderer.h" #import static inline size_t SDByteAlign(size_t size, size_t alignment) { @@ -337,16 +338,21 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over return image; } - CGImageRef imageRef = [self CGImageCreateDecoded:image.CGImage]; + CGImageRef imageRef = image.CGImage; if (!imageRef) { return image; } -#if SD_MAC - UIImage *decodedImage = [[UIImage alloc] initWithCGImage:imageRef scale:image.scale orientation:kCGImagePropertyOrientationUp]; -#else - UIImage *decodedImage = [[UIImage alloc] initWithCGImage:imageRef scale:image.scale orientation:image.imageOrientation]; -#endif - CGImageRelease(imageRef); + BOOL hasAlpha = [self CGImageContainsAlpha:imageRef]; + // Prefer to use new Image Renderer to re-draw image, instead of low-level CGBitmapContext and CGContextDrawImage + // This can keep both OS compatible and don't fight with Apple's performance optimization + SDGraphicsImageRendererFormat *format = [[SDGraphicsImageRendererFormat alloc] init]; + format.opaque = !hasAlpha; + format.scale = image.scale; + CGSize imageSize = image.size; + SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:imageSize format:format]; + UIImage *decodedImage = [renderer imageWithActions:^(CGContextRef _Nonnull context) { + [image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)]; + }]; SDImageCopyAssociatedObject(image, decodedImage); decodedImage.sd_isDecoded = YES; return decodedImage;