绿幕抠图代码实现和使用P图软件完成绿幕抠图的步骤是一致的,总共包括四步:
1、初始化前景图,需要P图的部分填充为纯色背景(绿幕/蓝幕)
2、把纯色部分的bitmap设置为透明
3、准备背景图(尺寸和前景图一致),前景图叠加到背景图生成目标图片
4、导出目标图片,完成抠图功能
纯色部分的bitmap设置为透明
- (CIFilter*) chromaKeyFilterHuesFrom:(CGFloat)minHue to:(CGFloat)maxHue{
// 1
const unsigned int size = 64;
const size_t cubeDataSize = size * size * size * 4;
NSMutableData* cubeData = [[NSMutableData alloc] initWithCapacity:
(cubeDataSize * sizeof(float))];
// 2
for (int z = 0; z < size; z++) {
CGFloat blue = ((double)z)/(size-1);
for (int y = 0; y < size; y++) {
CGFloat green = ((double)y)/(size-1);
for (int x = 0; x < size; x++) {
CGFloat red = ((double)x)/(size-1);
// 3
CGFloat hue = [self hueFromRed:red green:green blue:blue];
float alpha = (hue >= minHue && hue <= maxHue) ? 0 : 1;
// 4
float premultipliedRed = red * alpha;
float premultipliedGreen = green * alpha;
float premultipliedBlue = blue * alpha;
[cubeData AppendBytes:&premultipliedRed length:sizeof(float)];
[cubeData appendBytes:&premultipliedGreen length:sizeof(float)];
[cubeData appendBytes:&premultipliedBlue length:sizeof(float)];
[cubeData appendBytes:&alpha length:sizeof(float)];
}
}
}
// 5
CIFilter* chromaKeyFilter = [CIFilter filterWithName:@"CIColorCube"];
[chromaKeyFilter setValue:@(size) forKey:@"inputCubeDimension"];
[chromaKeyFilter setValue:cubeData forKey:@"inputCubeData"];
return chromaKeyFilter;
}
获取每个bitmap的颜色值
- (CGFloat) hueFromRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue {
UIColor* color = [UIColor colorWithRed:red green:green blue:blue alpha:1];
CGFloat hue, saturation, brightness;
[color getHue:&hue saturation:&saturation brightness:&brightness alpha:nil];
return hue;
}
前景图叠加到背景图,生成目标图片
- (CIImage *)outputImage{
CIFilter* chromaKeyFilter = [self chromaKeyFilterHuesFrom:0.3 to:0.4];
CIImage *myImage = [[CIImage alloc] initWithImage:self.inputFilterImage];
[chromaKeyFilter setValue:myImage forKey:kCIInputImageKey];
CIFilter* compositor = [CIFilter filterWithName:@"CISourceOverCompositing"];
CIImage* souceCIImage = chromaKeyFilter.outputImage;
[compositor setValue:souceCIImage forKey:kCIInputImageKey];
CIImage *backgroundCIImage = [[CIImage alloc] initWithImage:self.backgroundImage];
[compositor setValue:backgroundCIImage forKey:kCIInputBackgroundImageKey];
return compositor.outputImage;
}
最后,把生成的图片保存到系统相册,完成抠图功能。