Skip to content

Commit 4a3ce34

Browse files
authored
Merge pull request SDWebImage#3506 from dreampiggy/bugfix/fix_blur_effect
Fix the blur effect logic by avoid color convert and always use three box-blur methodology
2 parents 14b36f8 + e0b7cc5 commit 4a3ce34

File tree

1 file changed

+11
-20
lines changed

1 file changed

+11
-20
lines changed

SDWebImage/Core/UIImage+Transform.m

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -701,15 +701,8 @@ - (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius {
701701
#endif
702702

703703
CGImageRef imageRef = self.CGImage;
704-
705-
//convert to BGRA if it isn't
706-
if (CGImageGetBitsPerPixel(imageRef) != 32 ||
707-
CGImageGetBitsPerComponent(imageRef) != 8 ||
708-
!((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask))) {
709-
SDGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
710-
[self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
711-
imageRef = SDGraphicsGetImageFromCurrentImageContext().CGImage;
712-
SDGraphicsEndImageContext();
704+
if (!imageRef) {
705+
return nil;
713706
}
714707

715708
vImage_Buffer effect = {}, scratch = {};
@@ -726,7 +719,7 @@ - (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius {
726719
};
727720

728721
vImage_Error err;
729-
err = vImageBuffer_InitWithCGImage(&effect, &format, NULL, imageRef, kvImageNoFlags);
722+
err = vImageBuffer_InitWithCGImage(&effect, &format, NULL, imageRef, kvImageNoFlags); // vImage will convert to format we requests, no need `vImageConvert`
730723
if (err != kvImageNoError) {
731724
NSLog(@"UIImage+Transform error: vImageBuffer_InitWithCGImage returned error code %zi for inputImage: %@", err, self);
732725
return nil;
@@ -740,6 +733,7 @@ - (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius {
740733
input = &effect;
741734
output = &scratch;
742735

736+
// See: https://developer.apple.com/library/archive/samplecode/UIImageEffects/Introduction/Intro.html
743737
if (hasBlur) {
744738
// A description of how to compute the box kernel width from the Gaussian
745739
// radius (aka standard deviation) appears in the SVG spec:
@@ -756,19 +750,16 @@ - (nullable UIImage *)sd_blurredImageWithRadius:(CGFloat)blurRadius {
756750
if (inputRadius - 2.0 < __FLT_EPSILON__) inputRadius = 2.0;
757751
uint32_t radius = floor(inputRadius * 3.0 * sqrt(2 * M_PI) / 4 + 0.5);
758752
radius |= 1; // force radius to be odd so that the three box-blur methodology works.
759-
int iterations;
760-
if (blurRadius * scale < 0.5) iterations = 1;
761-
else if (blurRadius * scale < 1.5) iterations = 2;
762-
else iterations = 3;
763753
NSInteger tempSize = vImageBoxConvolve_ARGB8888(input, output, NULL, 0, 0, radius, radius, NULL, kvImageGetTempBufferSize | kvImageEdgeExtend);
764754
void *temp = malloc(tempSize);
765-
for (int i = 0; i < iterations; i++) {
766-
vImageBoxConvolve_ARGB8888(input, output, temp, 0, 0, radius, radius, NULL, kvImageEdgeExtend);
767-
vImage_Buffer *tmp = input;
768-
input = output;
769-
output = tmp;
770-
}
755+
vImageBoxConvolve_ARGB8888(input, output, temp, 0, 0, radius, radius, NULL, kvImageEdgeExtend);
756+
vImageBoxConvolve_ARGB8888(output, input, temp, 0, 0, radius, radius, NULL, kvImageEdgeExtend);
757+
vImageBoxConvolve_ARGB8888(input, output, temp, 0, 0, radius, radius, NULL, kvImageEdgeExtend);
771758
free(temp);
759+
760+
vImage_Buffer *tmp = input;
761+
input = output;
762+
output = tmp;
772763
}
773764

774765
CGImageRef effectCGImage = NULL;

0 commit comments

Comments
 (0)