iOS去除图片背景颜色的方法

2020-01-21 03:36:22王旭


32-bit and 16-bit pixel formats for CMYK and RGB color spaces in Quartz 2D

回到我们的需求,对于去除图片中的指定颜色,如果我们能够读取到每个像素上的RGBA信息,分别判断他们的值,如果符合目标范围,我们将他的Alpha值改为0,然后输出成新的图片,那么我们就实现了类似上文中cubeMap的处理方式。

强大的Quarz 2D为我们提供了实现这种操作的能力,下面请看代码示例:


- (UIImage *)removeColorWithMaxR:(float)maxR minR:(float)minR maxG:(float)maxG minG:(float)minG maxB:(float)maxB minB:(float)minB image:(UIImage *)image{
 // 分配内存
 const int imageWidth = image.size.width;
 const int imageHeight = image.size.height;
 size_t bytesPerRow = imageWidth * 4;
 uint32_t* rgbImageBuf = (uint32_t*)malloc(bytesPerRow * imageHeight);
 // 创建context
 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();// 色彩范围的容器
 CGContextRef context = CGBitmapContextCreate(rgbImageBuf, imageWidth, imageHeight, 8, bytesPerRow, colorSpace,kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
 CGContextDrawImage(context, CGRectMake(0, 0, imageWidth, imageHeight), image.CGImage);
 // 遍历像素
 int pixelNum = imageWidth * imageHeight;
 uint32_t* pCurPtr = rgbImageBuf;
 for (int i = 0; i < pixelNum; i++, pCurPtr++)
 {
 uint8_t* ptr = (uint8_t*)pCurPtr;
 if (ptr[3] >= minR && ptr[3] <= maxR &&
 ptr[2] >= minG && ptr[2] <= maxG &&
 ptr[1] >= minB && ptr[1] <= maxB) {
 ptr[0] = 0;
 }else{
 printf("n---->ptr0:%d ptr1:%d ptr2:%d ptr3:%d<----n",ptr[0],ptr[1],ptr[2],ptr[3]);
 }
 }
 // 将内存转成image
 CGDataProviderRef dataProvider =CGDataProviderCreateWithData(NULL, rgbImageBuf, bytesPerRow * imageHeight, nil);
 CGImageRef imageRef = CGImageCreate(imageWidth, imageHeight,8, 32, bytesPerRow, colorSpace,kCGImageAlphaLast |kCGBitmapByteOrder32Little, dataProvider,NULL,true,kCGRenderingIntentDefault);
 CGDataProviderRelease(dataProvider);
 UIImage* resultUIImage = [UIImage imageWithCGImage:imageRef]; 
 // 释放
 CGImageRelease(imageRef);
 CGContextRelease(context);
 CGColorSpaceRelease(colorSpace);
 return resultUIImage;
}

 

还记得我们在Core Image中提到的HSV模式的弊端吗?那么Quarz 2D则是直接利用RGBA的信息进行处理,很好的规避了对黑白色不友好的问题,我们只需要设置一下RGB的范围即可(因为黑白色在RGB颜色模式中,很好确定),我们可以大致封装一下。如下


- (UIImage *)removeWhiteColorWithImage:(UIImage *)image{
 return [self removeColorWithMaxR:255 minR:250 maxG:255 minG:240 maxB:255 minB:240 image:image];
}

- (UIImage *)removeBlackColorWithImage:(UIImage *)image{
 return [self removeColorWithMaxR:15 minR:0 maxG:15 minG:0 maxB:15 minB:0 image:image];
}