灰度图片和灰度颜色(代码里面只是一些相关的方法替换按需选取几个就好)
+ (UIImage *)convertToGrayscale:(UIImage*)sourceImage { return [self convertToGrayscale:sourceImage.CGImage scale:sourceImage.scale]; } + (UIImage *)convertToGrayscale:(CGImageRef)sourceImage scale:(CGFloat)scale { if (!sourceImage) { return nil; } UIImage *resultUIImage = nil; @autoreleasepool { int width = (int)CGImageGetWidth(sourceImage); int height = (int)CGImageGetHeight(sourceImage); // the pixels will be painted to this array uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t)); // clear the pixels so any transparency is preserved memset(pixels, 0, width * height * sizeof(uint32_t)); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // create a context with RGBA pixels CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast); // paint the bitmap to our context which will fill in the pixels array CGContextDrawImage(context, CGRectMake(0, 0, width, height), sourceImage); for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x]; // convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale uint8_t gray = (uint8_t)round(0.299 * rgbaPixel[1] + 0.587 * rgbaPixel[2] + 0.114 * rgbaPixel[3]); // set the pixels to gray rgbaPixel[1] = gray; rgbaPixel[2] = gray; rgbaPixel[3] = gray; } } // create a new CGImageRef from our context with the modified pixels CGImageRef image = CGBitmapContextCreateImage(context); // we're done with the context, color space, and pixels CGContextRelease(context); CGColorSpaceRelease(colorSpace); free(pixels); resultUIImage = [UIImage imageWithCGImage:image scale:scale orientation:UIImageOrientationUp]; // we're done with image now too CGImageRelease(image); } // make a new UIImage to return return resultUIImage; }
@interface CALayer (CustomerColorsLayer) @end @implementation CALayer (CustomerColorsLayer) + (void)load { // [self ms_swizzleMethod:@selector(setContents:) withMethod:@selector(mm_setContents:)]; // [self ms_swizzleMethod:@selector(drawInContext:) withMethod:@selector(mm_drawInContext:)]; } - (void)mm_setContents:(id)contents { static CFTypeID imageType = 0; if (imageType == 0) { imageType = CFGetTypeID([UIImage imageWithColor:[UIColor whiteColor]].CGImage); } if (contents != NULL && CFGetTypeID((__bridge CFTypeRef)(contents)) == imageType) { @autoreleasepool { UIImage *sourceImage = [UIImage imageWithCGImage:(__bridge CGImageRef _Nonnull)(contents)]; UIImage *grayImage = [UIImage convertToGrayscale:sourceImage]; [self mm_setContents:(__bridge id)grayImage.CGImage]; } } else { [self mm_setContents:contents]; } } // 这个方法无效 - (void)mm_drawInContext:(CGContextRef)ctx { CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); CGContextSetFillColorSpace(ctx, colorSpace); [self mm_drawInContext:ctx]; CGColorSpaceRelease(colorSpace); } @end @interface UIImageView (CustomerColorsLayer) @end @implementation UIImageView (CustomerColorsLayer) + (void)load { [self ms_swizzleMethod:@selector(setImage:) withMethod:@selector(mm_setImage:)]; } - (void)mm_setImage:(UIImage *)image { [self mm_setImage:[UIImage convertToGrayscale:image]]; } @end // 这个方法一定要有 @interface UIColor (CustomerColorsLayer) @end @implementation UIColor (CustomerColorsLayer) + (void)load { [self ms_swizzleClassMethod:@selector(colorWithRed:green:blue:alpha:) withMethod:@selector(grayColorWithRed:green:blue:alpha:)]; } + (UIColor *)grayColorWithRed:(CGFloat)r green:(CGFloat)g blue:(CGFloat)b alpha:(CGFloat)a { CGFloat gray = r * 0.299 +g * 0.587 + b * 0.114; UIColor *grayColor = [UIColor grayColorWithRed:gray green:gray blue:gray alpha:a]; return grayColor; } @end
图片全部通过SD加载时使用以下方案:
@interface SDImageIOAnimatedCoder (CustomerColorsLayer) + (UIImage *)createFrameAtIndex:(NSUInteger)index source:(CGImageSourceRef)source scale:(CGFloat)scale preserveAspectRatio:(BOOL)preserveAspectRatio thumbnailSize:(CGSize)thumbnailSize options:(NSDictionary *)options; @end @implementation SDImageIOAnimatedCoder (CustomerColorsLayer) + (void)load { [self ms_swizzleClassMethod:@selector(createFrameAtIndex:source:scale:preserveAspectRatio:thumbnailSize:options:) withMethod:@selector(mmCreateFrameAtIndex:source:scale:preserveAspectRatio:thumbnailSize:options:)]; } + (nullable UIImage *)mmCreateFrameAtIndex:(NSUInteger)index source:(nonnull CGImageSourceRef)source scale:(CGFloat)scale preserveAspectRatio:(BOOL)preserveAspectRatio thumbnailSize:(CGSize)thumbnailSize options:(nullable NSDictionary *)options { UIImage *image = [self mmCreateFrameAtIndex:index source:source scale:scale preserveAspectRatio:preserveAspectRatio thumbnailSize:thumbnailSize options:options]; return [UIImage convertToGrayscale:image]; } @end
使用CoreImage框架里面的方法,性能会好一些
+ (UIImage*)updateDataToGrayImage:(UIImage*)sourceImage { CIFilter * filter = [CIFilter filterWithName:@"CIColorControls"]; [filter setValue:[CIImage imageWithCGImage:sourceImage.CGImage] forKey:kCIInputImageKey]; //饱和度 0---2 默认为1 [filter setValue:@0 forKey:kCIInputSaturationKey]; CIImage *inputImage; if (sourceImage.CIImage) { inputImage = sourceImage.CIImage; } else { CGImageRef imageRef = sourceImage.CGImage; if (!imageRef) { return nil; } inputImage = [CIImage imageWithCGImage:imageRef]; } if (!inputImage) return nil; CIContext *context = [CIContext context]; [filter setValue:inputImage forKey:kCIInputImageKey]; CIImage *outputImage = filter.outputImage; if (!outputImage) return nil; CGImageRef imageRef = [context createCGImage:outputImage fromRect:outputImage.extent]; if (!imageRef) return nil; UIImage *image = [UIImage imageWithCGImage:imageRef scale:sourceImage.scale orientation:sourceImage.imageOrientation]; CGImageRelease(imageRef); return image; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步