|
13 | 13 | @implementation UIImage (ForceDecode)
|
14 | 14 |
|
15 | 15 | + (UIImage *)decodedImageWithImage:(UIImage *)image {
|
16 |
| - if (image.images) { |
17 |
| - // Do not decode animated images |
18 |
| - return image; |
19 |
| - } |
| 16 | + // do not decode animated images |
| 17 | + if (image.images) { return image; } |
20 | 18 |
|
21 | 19 | CGImageRef imageRef = image.CGImage;
|
22 |
| - CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); |
23 |
| - CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize}; |
24 | 20 |
|
25 |
| - CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); |
26 |
| - CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); |
| 21 | + CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef); |
| 22 | + BOOL anyAlpha = (alpha == kCGImageAlphaFirst || |
| 23 | + alpha == kCGImageAlphaLast || |
| 24 | + alpha == kCGImageAlphaPremultipliedFirst || |
| 25 | + alpha == kCGImageAlphaPremultipliedLast); |
27 | 26 |
|
28 |
| - int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask); |
29 |
| - BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || |
30 |
| - infoMask == kCGImageAlphaNoneSkipFirst || |
31 |
| - infoMask == kCGImageAlphaNoneSkipLast); |
| 27 | + if (anyAlpha) { return image; } |
32 | 28 |
|
33 |
| - // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB. |
34 |
| - // https://developer.apple.com/library/mac/#qa/qa1037/_index.html |
35 |
| - if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) { |
36 |
| - // Unset the old alpha info. |
37 |
| - bitmapInfo &= ~kCGBitmapAlphaInfoMask; |
| 29 | + size_t width = CGImageGetWidth(imageRef); |
| 30 | + size_t height = CGImageGetHeight(imageRef); |
38 | 31 |
|
39 |
| - // Set noneSkipFirst. |
40 |
| - bitmapInfo |= kCGImageAlphaNoneSkipFirst; |
41 |
| - } |
42 |
| - // Some PNGs tell us they have alpha but only 3 components. Odd. |
43 |
| - else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) { |
44 |
| - // Unset the old alpha info. |
45 |
| - bitmapInfo &= ~kCGBitmapAlphaInfoMask; |
46 |
| - bitmapInfo |= kCGImageAlphaPremultipliedFirst; |
47 |
| - } |
| 32 | + CGContextRef context = CGBitmapContextCreate(NULL, width, |
| 33 | + height, |
| 34 | + CGImageGetBitsPerComponent(imageRef), |
| 35 | + 0, |
| 36 | + CGImageGetColorSpace(imageRef), |
| 37 | + kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst); |
48 | 38 |
|
49 |
| - // It calculates the bytes-per-row based on the bitsPerComponent and width arguments. |
50 |
| - CGContextRef context = CGBitmapContextCreate(NULL, |
51 |
| - imageSize.width, |
52 |
| - imageSize.height, |
53 |
| - CGImageGetBitsPerComponent(imageRef), |
54 |
| - 0, |
55 |
| - colorSpace, |
56 |
| - bitmapInfo); |
57 |
| - CGColorSpaceRelease(colorSpace); |
58 |
| - |
59 |
| - // If failed, return undecompressed image |
60 |
| - if (!context) return image; |
61 |
| - |
62 |
| - CGContextDrawImage(context, imageRect, imageRef); |
63 |
| - CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); |
| 39 | + // Draw the image into the context and retrieve the new image, which will now have an alpha layer |
| 40 | + CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); |
| 41 | + CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(context); |
| 42 | + UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha]; |
64 | 43 |
|
65 | 44 | CGContextRelease(context);
|
| 45 | + CGImageRelease(imageRefWithAlpha); |
66 | 46 |
|
67 |
| - UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; |
68 |
| - CGImageRelease(decompressedImageRef); |
69 |
| - return decompressedImage; |
| 47 | + return imageWithAlpha; |
70 | 48 | }
|
71 | 49 |
|
72 | 50 | @end
|
0 commit comments