iOS去除图片背景颜色的方法去除图片背景颜色的方法
本篇文章给大家分享一下iOS去除图片中指定范围内颜色的三种方式,需要的朋友参考学习下吧。
实际项目场景:去除图片的纯白色背景图,获得一张透明底图片用于拼图功能
介绍两种途径的三种处理方式(不知道为啥想起了孔乙己),具体性能鶸并未对比,如果有大佬能告知,不胜感激。
Core Image Core Graphics/Quarz 2D Core Image
Core Image是一个很强大的框架。它可以让你简单地应用各种滤镜来处理图像,比如修改鲜艳程度,色泽,或者曝光。 它利用GPU(或者CPU)来非常快速、甚至实时地处理图
像数据和视频的帧。并且隐藏了底层图形处理的所有细节,通过提供的API就能简单的使用了,无须关心OpenGL或者OpenGL ES是如何充分利用GPU的能力的,也不需要你
知道GCD在其中发挥了怎样的作用,Core Image处理了全部的细节。
在苹果官方文档Core Image Programming Guide中,提到了Chroma Key Filter Recipe对于处理背景的范例
其中使用了HSV颜色模型,因为HSV模型,对于颜色范围的表示,相比RGB更加友好。
大致过程处理过程:
创建一个映射希望移除颜色值范围的立方体贴图cubeMap,将目标颜色的Alpha置为0.0f 使用CIColorCube滤镜和cubeMap对源图像进行颜色处理获取到经过CIColorCube处理的Core
Image对象CIImage,转换为Core Graphics中的CGImageRef对象,通过imageWithCGImage:获取结果图片
注意:第三步中,不可以直接使用imageWithCIImage:,因为得到的并不是一个标准的UIImage,如果直接拿来用,会出现不显示的情况。
- (UIImage *)removeColorWithMinHueAngle:(float)minHueAngle maxHueAngle:(float)maxHueAngle image:(UIImage *)originalImage{
CIImage *image = [CIImage imageWithCGImage:originalImage.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];// kCIContextUseSoftwareRenderer : CPURender
/** 注意
* UIImage 通过CIimage初始化,得到的并不是一个通过类似CGImage的标准UIImage
* 所以如果不用context进行渲染处理,是没办法正常显示的
*/
CIImage *renderBgImage = [self outputImageWithOriginalCIImage:image minHueAngle:minHueAngle maxHueAngle:maxHueAngle];
CGImageRef renderImg = [context createCGImage:renderBgImage fromRect:image.extent];
UIImage *renderImage = [UIImage imageWithCGImage:renderImg];
return renderImage;
}
struct CubeMap {
int length;
float dimension;
float *data;
};
- (CIImage *)outputImageWithOriginalCIImage:(CIImage *)originalImage minHueAngle:(float)minHueAngle maxHueAngle:(float)maxHueAngle{
struct CubeMap map = createCubeMap(minHueAngle, maxHueAngle);
const unsigned int size = 64;
// Create memory with the cube data
NSData *data = [NSData dataWithBytesNoCopy:map.data
length:map.length
freeWhenDone:YES];
CIFilter *colorCube = [CIFilter filterWithName:@"CIColorCube"];
[colorCube setValue:@(size) forKey:@"inputCubeDimension"];
// Set data for cube
[colorCube setValue:data forKey:@"inputCubeData"];
[colorCube setValue:originalImage forKey:kCIInputImageKey];
CIImage *result = [colorCube valueForKey:kCIOutputImageKey];
return result;
}
struct CubeMap createCubeMap(float minHueAngle, float maxHueAngle) {
const unsigned int size = 64;
struct CubeMap map;
map.length = size * size * size * sizeof (float) * 4;
map.dimension = size;
float *cubeData = (float *)malloc (map.length);
float rgb[3], hsv[3], *c = cubeData;
for (int z = 0; z < size; z++){
rgb[2] = ((double)z)/(size-1); // Blue value
for (int y = 0; y < size; y++){
rgb[1] = ((double)y)/(size-1); // Green value
for (int x = 0; x < size; x ++){
rgb[0] = ((double)x)/(size-1); // Red value
rgbToHSV(rgb,hsv);
// Use the hue value to determine which to make transparent
// The minimum and maximum hue angle depends on
// the color you want to remove
float alpha = (hsv[0] > minHueAngle && hsv[0] < maxHueAngle) ? 0.0f: 1.0f;
// Calculate premultiplied alpha values for the cube
c[0] = rgb[0] * alpha;
c[1] = rgb[1] * alpha;
c[2] = rgb[2] * alpha;
c[3] = alpha;
c += 4; // advance our pointer into memory for the next color value
}
}
}
map.data = cubeData;
return map;
}