如何使UIImage上的一个颜色透明?

在我的iPhone应用程序,我有一个UIImage实例。 我想获得一个UIImage,它是第一个UIImage的结果,其中一个颜色(例如洋红色)是透明的。 我该怎么做?

-(void)changeColor { UIImage *temp23=[UIImage imageNamed:@"leaf.png"]; CGImageRef ref1=[self createMask:temp23]; const float colorMasking[6] = {1.0, 2.0, 1.0, 1.0, 1.0, 1.0}; CGImageRef New=CGImageCreateWithMaskingColors(ref1, colorMasking); UIImage *resultedimage=[UIImage imageWithCGImage:New]; } -(CGImageRef)createMask:(UIImage*)temp { CGImageRef ref=temp.CGImage; int mWidth=CGImageGetWidth(ref); int mHeight=CGImageGetHeight(ref); int count=mWidth*mHeight*4; void *bufferdata=malloc(count); CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault; CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; CGContextRef cgctx = CGBitmapContextCreate (bufferdata,mWidth,mHeight, 8,mWidth*4, colorSpaceRef, kCGImageAlphaPremultipliedFirst); CGRect rect = {0,0,mWidth,mHeight}; CGContextDrawImage(cgctx, rect, ref); bufferdata = CGBitmapContextGetData (cgctx); CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bufferdata, mWidth*mHeight*4, NULL); CGImageRef savedimageref = CGImageCreate(mWidth,mHeight, 8, 32, mWidth*4, colorSpaceRef, bitmapInfo,provider , NULL, NO, renderingIntent); CFRelease(colorSpaceRef); return savedimageref; } 

上面的代码已经过testing,我用掩码把绿色改成了红色

好。 已经尝试过,我不知道这些解决scheme有多less个版本,我有我自己的定制版本。 我发现@yubenyi的解决scheme工作得很好,但是如果你想从他的changeWhiteColorTransparent()函数获取输出并将其传递回去,那么它就不起作用。

我的第一步是改变他的function,接受一个特定的颜色和宽容,让来电者可以指定一系列的颜色,使透明。 这工作得很好,几乎不变,但我发现,输出是不是一个有效的图像传递相同的代码与第二个颜色范围。

经过大量的试验和错误,我自己做了颜色replace,我得到了这个工作。 我反对这个,因为当API有这样的东西的时候,看起来太辛苦了,但是他们并不总是按照你想要的方式行事。 具体而言,CGImageCreateWithMaskingColors()的输出不能用作对同一函数的另一个调用的input。 我还没有弄清楚为什么,但是我认为这与alpha通道有关。

无论如何,我的解决scheme是:

 - (UIImage*) replaceColor:(UIColor*)color inImage:(UIImage*)image withTolerance:(float)tolerance { CGImageRef imageRef = [image CGImage]; NSUInteger width = CGImageGetWidth(imageRef); NSUInteger height = CGImageGetHeight(imageRef); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); NSUInteger bytesPerPixel = 4; NSUInteger bytesPerRow = bytesPerPixel * width; NSUInteger bitsPerComponent = 8; NSUInteger bitmapByteCount = bytesPerRow * height; unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char)); CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); CGColorRef cgColor = [color CGColor]; const CGFloat *components = CGColorGetComponents(cgColor); float r = components[0]; float g = components[1]; float b = components[2]; //float a = components[3]; // not needed r = r * 255.0; g = g * 255.0; b = b * 255.0; const float redRange[2] = { MAX(r - (tolerance / 2.0), 0.0), MIN(r + (tolerance / 2.0), 255.0) }; const float greenRange[2] = { MAX(g - (tolerance / 2.0), 0.0), MIN(g + (tolerance / 2.0), 255.0) }; const float blueRange[2] = { MAX(b - (tolerance / 2.0), 0.0), MIN(b + (tolerance / 2.0), 255.0) }; int byteIndex = 0; while (byteIndex < bitmapByteCount) { unsigned char red = rawData[byteIndex]; unsigned char green = rawData[byteIndex + 1]; unsigned char blue = rawData[byteIndex + 2]; if (((red >= redRange[0]) && (red <= redRange[1])) && ((green >= greenRange[0]) && (green <= greenRange[1])) && ((blue >= blueRange[0]) && (blue <= blueRange[1]))) { // make the pixel transparent // rawData[byteIndex] = 0; rawData[byteIndex + 1] = 0; rawData[byteIndex + 2] = 0; rawData[byteIndex + 3] = 0; } byteIndex += 4; } CGImageRef imgref = CGBitmapContextCreateImage(context); UIImage *result = [UIImage imageWithCGImage:imgref]; CGImageRelease(imgref); CGContextRelease(context); free(rawData); return result; } 

这是yubenyi的代码的一个调整,将多次通过工作。 它在处理之前通过将图像转换为未压缩的jpeg来去除alpha通道。 还添加了一些关于颜色范围select如何工作的评论。

 -(UIImage *)changeWhiteColorTransparent: (UIImage *)image { //convert to uncompressed jpg to remove any alpha channels //this is a necessary first step when processing images that already have transparency image = [UIImage imageWithData:UIImageJPEGRepresentation(image, 1.0)]; CGImageRef rawImageRef=image.CGImage; //RGB color range to mask (make transparent) R-Low, R-High, G-Low, G-High, B-Low, B-High const double colorMasking[6] = {222, 255, 222, 255, 222, 255}; UIGraphicsBeginImageContext(image.size); CGImageRef maskedImageRef=CGImageCreateWithMaskingColors(rawImageRef, colorMasking); //iPhone translation CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, image.size.height); CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0); CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), maskedImageRef); UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); CGImageRelease(maskedImageRef); UIGraphicsEndImageContext(); return result; } 

这个function可以工作!

 -(UIImage *)changeWhiteColorTransparent: (UIImage *)image { CGImageRef rawImageRef=image.CGImage; const float colorMasking[6] = {222, 255, 222, 255, 222, 255}; UIGraphicsBeginImageContext(image.size); CGImageRef maskedImageRef=CGImageCreateWithMaskingColors(rawImageRef, colorMasking); { //if in iphone CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0, image.size.height); CGContextScaleCTM(UIGraphicsGetCurrentContext(), 1.0, -1.0); } CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, image.size.width, image.size.height), maskedImageRef); UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); CGImageRelease(maskedImageRef); UIGraphicsEndImageContext(); return result; } 

使用你的function后,我发现更简单的方式为UIImage制作透明背景:)

例如,您有黑色背景的PNG图像,并且希望在屏幕上使该背景透明。

你可以试试这个:

 UIImage * image = [UIImage imageNamed:@"image.png"]; const CGFloat colorMasking[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; image = [UIImage imageWithCGImage: CGImageCreateWithMaskingColors(image.CGImage, colorMasking)]; 

你有透明背景的图像。

就这样 :)

我从来没有做过这样的事情,但它看起来像CGImageCreateWithMaskingColors可能在这里使用。 使用核心graphics超出了我可以在本网站的答案解释的范围,虽然; 看看你的文档,并在网上search教程。

基于@PKCLsoft的高超的答案,我做了一个编辑,只让白色透明,但是它使得alpha是基于像素是多么“白”的。 当你试图用黑白图像制作一个蒙版时,这可能会得心应手,所以它会在文本或形状上提供平滑的边缘。

 - (UIImage *)makeWhiteColorTransparentInImage:(UIImage *)image { CGImageRef imageRef = [image CGImage]; NSUInteger width = CGImageGetWidth(imageRef); NSUInteger height = CGImageGetHeight(imageRef); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); NSUInteger bytesPerPixel = 4; NSUInteger bytesPerRow = bytesPerPixel * width; NSUInteger bitsPerComponent = 8; NSUInteger bitmapByteCount = bytesPerRow * height; unsigned char *rawData = (unsigned char*) calloc(bitmapByteCount, sizeof(unsigned char)); CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); int byteIndex = 0; while (byteIndex < bitmapByteCount) { unsigned char red = rawData[byteIndex]; unsigned char green = rawData[byteIndex + 1]; unsigned char blue = rawData[byteIndex + 2]; unsigned char alpha = rawData[byteIndex + 3]; if (alpha == 0.0) { rawData[byteIndex + 3] = 0.0; } else { rawData[byteIndex + 3] = 255.0 - (red + green + blue) / 3.0; } byteIndex += 4; } CGImageRef imgref = CGBitmapContextCreateImage(context); UIImage *result = [UIImage imageWithCGImage:imgref]; CGImageRelease(imgref); CGContextRelease(context); free(rawData); return result; } 

我希望有一天能帮助别人:)

这里是Swift 4兼容的UIImage扩展。 调整colorMasking数组中的'200'值,直到对结果满意为止。 接近255的值过滤掉较less的白色,接近0的值过滤掉较多的白色。

 extension UIImage { func imageByMakingWhiteBackgroundTransparent() -> UIImage? { if let rawImageRef = self.cgImage { let colorMasking: [CGFloat] = [200, 255, 200, 255, 200, 255] return UIImage(cgImage: rawImageRef.copy(maskingColorComponents: colorMasking)!) } return nil }