1111#import " QMUIConfiguration.h"
1212#import " QMUIHelper.h"
1313#import " UIBezierPath+QMUI.h"
14+ #import " UIColor+QMUI.h"
1415#import < Accelerate/Accelerate.h>
1516
1617CG_INLINE CGSize
@@ -57,44 +58,41 @@ - (UIImage *)qmui_grayImage {
5758 NSInteger width = self.size .width * self.scale ;
5859 NSInteger height = self.size .height * self.scale ;
5960 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray ();
60- CGContextRef context = CGBitmapContextCreate (nil , width, height, 8 , 0 , colorSpace, kCGBitmapByteOrderDefault );
61+ CGContextRef context = CGBitmapContextCreate (NULL , width, height, 8 , 0 , colorSpace, kCGBitmapByteOrderDefault );
6162 CGContextInspectContext (context);
6263 CGColorSpaceRelease (colorSpace);
6364 if (context == NULL ) {
6465 return nil ;
6566 }
66-
67- CGContextDrawImage (context,CGRectMake (0 , 0 , width, height), self.CGImage );
68- CGImageRef grayImageRef = CGBitmapContextCreateImage (context);
69- CGContextRelease (context);
70-
71- CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo (self.CGImage );
72- BOOL opaque = (alphaInfo == kCGImageAlphaNoneSkipLast ) ||
73- (alphaInfo == kCGImageAlphaNoneSkipFirst ) ||
74- (alphaInfo == kCGImageAlphaNone );
75-
76- if (opaque) {
77- UIImage *qmui_grayImage = [UIImage imageWithCGImage: grayImageRef scale: self .scale orientation: self .imageOrientation];
78- CGImageRelease (grayImageRef);
79- return qmui_grayImage;
80- }
81-
82- context = CGBitmapContextCreate (NULL , width, height, 8 , 0 , NULL , kCGImageAlphaOnly );
83- CGContextDrawImage (context, CGRectMake (0 , 0 , width, height), self.CGImage );
84- CGImageRef maskImageRef = CGBitmapContextCreateImage (context);
85- CGImageRef maskedGrayImageRef = CGImageCreateWithMask (grayImageRef, maskImageRef);
86-
87- CGContextRelease (context);
88- CGImageRelease (grayImageRef);
89- CGImageRelease (maskImageRef);
90-
91- UIImage *maskedGrayImage = [UIImage imageWithCGImage: maskedGrayImageRef scale: self .scale orientation: self .imageOrientation];
92- CGImageRelease (maskedGrayImageRef);
93- return maskedGrayImage;
67+ CGRect imageRect = CGRectMake (0 , 0 , width, height);
68+ CGContextDrawImage (context, imageRect, self.CGImage );
69+
70+ UIImage *grayImage = nil ;
71+ CGImageRef imageRef = CGBitmapContextCreateImage (context);
72+ if (self.qmui_opaque ) {
73+ grayImage = [UIImage imageWithCGImage: imageRef scale: self .scale orientation: self .imageOrientation];
74+ } else {
75+ CGContextRef alphaContext = CGBitmapContextCreate (NULL , width, height, 8 , 0 , nil , kCGImageAlphaOnly );
76+ CGContextDrawImage (alphaContext, imageRect, self.CGImage );
77+ CGImageRef mask = CGBitmapContextCreateImage (alphaContext);
78+ grayImage = [UIImage imageWithCGImage: CGImageCreateWithMask (imageRef, mask) scale: self .scale orientation: self .imageOrientation];
79+ CGImageRelease (mask);
80+ CGContextRelease (alphaContext);
81+
82+ // 用 CGBitmapContextCreateImage 方式创建出来的图片,CGImageAlphaInfo 总是为 CGImageAlphaInfoNone,导致 qmui_opaque 与原图不一致,所以这里再做多一步
83+ UIGraphicsBeginImageContextWithOptions (grayImage.size , NO , grayImage.scale );
84+ [grayImage drawInRect: imageRect];
85+ grayImage = UIGraphicsGetImageFromCurrentImageContext ();
86+ UIGraphicsEndImageContext ();
87+ }
88+
89+ CGContextRelease (context);
90+ CGImageRelease (imageRef);
91+ return grayImage;
9492}
9593
9694- (UIImage *)qmui_imageWithAlpha : (CGFloat)alpha {
97- UIGraphicsBeginImageContextWithOptions (self.size , NO , self.scale );
95+ UIGraphicsBeginImageContextWithOptions (self.size , self. qmui_opaque , self.scale );
9896 CGContextRef context = UIGraphicsGetCurrentContext ();
9997 CGContextInspectContext (context);
10098 CGRect drawingRect = CGRectMake (0 , 0 , self.size .width , self.size .height );
@@ -104,10 +102,18 @@ - (UIImage *)qmui_imageWithAlpha:(CGFloat)alpha {
104102 return imageOut;
105103}
106104
105+ - (BOOL )qmui_opaque {
106+ CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo (self.CGImage );
107+ BOOL opaque = alphaInfo == kCGImageAlphaNoneSkipLast
108+ || alphaInfo == kCGImageAlphaNoneSkipFirst
109+ || alphaInfo == kCGImageAlphaNone ;
110+ return opaque;
111+ }
112+
107113- (UIImage *)qmui_imageWithTintColor : (UIColor *)tintColor {
108114 UIImage *imageIn = self;
109115 CGRect rect = CGRectMake (0 , 0 , imageIn.size .width , imageIn.size .height );
110- UIGraphicsBeginImageContextWithOptions (imageIn.size , NO , imageIn.scale );
116+ UIGraphicsBeginImageContextWithOptions (imageIn.size , self. qmui_opaque , imageIn.scale );
111117 CGContextRef context = UIGraphicsGetCurrentContext ();
112118 CGContextInspectContext (context);
113119 CGContextTranslateCTM (context, 0 , imageIn.size .height );
@@ -124,7 +130,7 @@ - (UIImage *)qmui_imageWithTintColor:(UIColor *)tintColor {
124130- (UIImage *)qmui_imageWithImageAbove : (UIImage *)image atPoint : (CGPoint)point {
125131 UIImage *imageIn = self;
126132 UIImage *imageOut = nil ;
127- UIGraphicsBeginImageContextWithOptions (imageIn.size , NO , imageIn.scale );
133+ UIGraphicsBeginImageContextWithOptions (imageIn.size , self. qmui_opaque , imageIn.scale );
128134 [imageIn drawInRect: CGRectMakeWithSize (imageIn.size)];
129135 [image drawAtPoint: point];
130136 imageOut = UIGraphicsGetImageFromCurrentImageContext ();
@@ -134,7 +140,7 @@ - (UIImage *)qmui_imageWithImageAbove:(UIImage *)image atPoint:(CGPoint)point {
134140
135141- (UIImage *)qmui_imageWithSpacingExtensionInsets : (UIEdgeInsets)extension {
136142 CGSize contextSize = CGSizeMake (self.size .width + UIEdgeInsetsGetHorizontalValue (extension), self.size .height + UIEdgeInsetsGetVerticalValue (extension));
137- UIGraphicsBeginImageContextWithOptions (contextSize, NO , self.scale );
143+ UIGraphicsBeginImageContextWithOptions (contextSize, self. qmui_opaque , self.scale );
138144 [self drawAtPoint: CGPointMake (extension.left, extension.top)];
139145 UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext ();
140146 UIGraphicsEndImageContext ();
@@ -143,10 +149,15 @@ - (UIImage *)qmui_imageWithSpacingExtensionInsets:(UIEdgeInsets)extension {
143149
144150- (UIImage *)qmui_imageWithClippedRect : (CGRect)rect {
145151 CGContextInspectSize (rect.size );
152+ CGRect imageRect = CGRectMakeWithSize (self.size );
153+ if (CGRectContainsRect (rect, imageRect)) {
154+ // 要裁剪的区域比自身大,所以不用裁剪直接返回自身即可
155+ return self;
156+ }
146157 // 由于CGImage是以pixel为单位来计算的,而UIImage是以point为单位,所以这里需要将传进来的point转换为pixel
147158 CGRect scaledRect = CGRectApplyScale (rect, self.scale );
148159 CGImageRef imageRef = CGImageCreateWithImageInRect (self.CGImage , scaledRect);
149- UIImage *imageOut = [UIImage imageWithCGImage: imageRef scale: self .scale orientation: UIImageOrientationUp ];
160+ UIImage *imageOut = [UIImage imageWithCGImage: imageRef scale: self .scale orientation: self .imageOrientation ];
150161 CGImageRelease (imageRef);
151162 return imageOut;
152163}
@@ -158,9 +169,12 @@ - (UIImage *)qmui_imageWithScaleToSize:(CGSize)size contentMode:(UIViewContentMo
158169- (UIImage *)qmui_imageWithScaleToSize : (CGSize)size contentMode : (UIViewContentMode)contentMode scale : (CGFloat)scale {
159170 size = CGSizeFlatSpecificScale (size, scale);
160171 CGContextInspectSize (size);
172+ UIGraphicsBeginImageContextWithOptions (size, self.qmui_opaque , scale);
173+ CGContextRef context = UIGraphicsGetCurrentContext ();
174+ CGContextInspectContext (context);
161175 CGSize imageSize = self.size ;
162176 CGRect drawingRect = CGRectZero;
163-
177+
164178 if (contentMode == UIViewContentModeScaleToFill) {
165179 drawingRect = CGRectMakeWithSize (size);
166180 } else {
@@ -177,16 +191,7 @@ - (UIImage *)qmui_imageWithScaleToSize:(CGSize)size contentMode:(UIViewContentMo
177191 drawingRect.size .height = flatfSpecificScale (imageSize.height * ratio, scale);
178192 drawingRect = CGRectSetXY (drawingRect, flatfSpecificScale ((size.width - CGRectGetWidth (drawingRect)) / 2.0 , scale), flatfSpecificScale ((size.height - CGRectGetHeight (drawingRect)) / 2 , scale));
179193 }
180-
181- CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo (self.CGImage );
182- BOOL opaque = (alphaInfo == kCGImageAlphaNoneSkipLast ) ||
183- (alphaInfo == kCGImageAlphaNoneSkipFirst ) ||
184- (alphaInfo == kCGImageAlphaNone );
185- opaque = (opaque && CGRectContainsRect (drawingRect, CGRectMakeWithSize (size)));
186-
187- UIGraphicsBeginImageContextWithOptions (size, opaque, scale);
188- CGContextRef context = UIGraphicsGetCurrentContext ();
189- CGContextInspectContext (context);
194+
190195 [self drawInRect: drawingRect];
191196 UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext ();
192197 UIGraphicsEndImageContext ();
@@ -259,7 +264,7 @@ - (UIImage *)qmui_imageWithBorderColor:(UIColor *)borderColor path:(UIBezierPath
259264 UIImage *oldImage = self;
260265 UIImage *resultImage;
261266 CGRect rect = CGRectMake (0 , 0 , oldImage.size .width , oldImage.size .height );
262- UIGraphicsBeginImageContextWithOptions (oldImage.size , NO , oldImage.scale );
267+ UIGraphicsBeginImageContextWithOptions (oldImage.size , self. qmui_opaque , oldImage.scale );
263268 CGContextRef context = UIGraphicsGetCurrentContext ();
264269 CGContextInspectContext (context);
265270 [oldImage drawInRect: rect];
@@ -323,10 +328,6 @@ - (UIImage *)qmui_imageWithBorderColor:(UIColor *)borderColor borderWidth:(CGFlo
323328 return self;
324329}
325330
326- void dataProviderReleaseCallback (void *info, const void *data, size_t size) {
327- free ((void *)data);
328- }
329-
330331- (UIImage *)qmui_imageWithMaskImage : (UIImage *)maskImage usingMaskImageMode : (BOOL )usingMaskImageMode {
331332 CGImageRef maskRef = [maskImage CGImage ];
332333 CGImageRef mask;
@@ -423,7 +424,8 @@ + (UIImage *)qmui_imageWithColor:(UIColor *)color size:(CGSize)size cornerRadius
423424 UIImage *resultImage = nil ;
424425 color = color ? color : UIColorClear;
425426
426- UIGraphicsBeginImageContextWithOptions (size, NO , 0 );
427+ BOOL opaque = [color qmui_alpha ] == 1.0 ;// 颜色本身不带透明,就不用创建带透明通道的 image 了
428+ UIGraphicsBeginImageContextWithOptions (size, opaque, 0 );
427429 CGContextRef context = UIGraphicsGetCurrentContext ();
428430 CGContextSetFillColorWithColor (context, color.CGColor );
429431
0 commit comments