如何在Xcode中使用图像过渡滤镜?

时间:2012-04-12 21:55:06

标签: objective-c ios image-processing core-image

在Ray Wenderlich的网站上成功跟踪tutorial之后,我决定尝试操纵我学到的东西并将其应用于CITransition,特别是CIDissolveTransition。然而,即使在交叉引用我所学到的反对Apple自己的过滤器文档之后,我似乎也无法显示图像(我要说,这些文档已过时并且非常难以在他们自己的复杂示例之外进行调整)。以下是我到目前为止的情况:

NSURL *url = [NSURL fileURLWithPath:imagePath];
NSURL *url2 = [NSURL fileURLWithPath:image2Path];
CIContext *context;
CIFilter *filter;
CIImage *beginImage, *targetImage;
UIImageView *mainImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
[self addSubview:mainImage];

beginImage = [CIImage imageWithContentsOfURL:url];
targetImage = [CIImage imageWithContentsOfURL:url2];

if(context == nil)
{
  NSLog(@"Creating Context");
  context = [CIContext contextWithOptions:nil];
}
if(filter == nil) {
  NSLog(@"Creating filter");
  filter = [CIFilter filterWithName:@"CIDissolveTransition" keysAndValues:@"inputImage",   beginImage, @"inputTargetImage", targetImage, @"inputTime", [NSNumber numberWithFloat:0.5], nil];
}

CIImage *outputImage = [filter outputImage];

CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg];

[mainImage setImage:newImg];

我所得到的只是一个黑屏,应该显示mainImage。最终的目标是能够使用滑块(我假设它可以工作)使用这种溶解效果循环一系列图像,但我甚至无法显示此静态图像。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:6)

您对filterWithName:keysAndValues:的调用返回nil,因为iOS不知道如何制作CIDossolveTransition过滤器。 适用于iOS的Core Image不支持Mac OS核心映像的所有过滤器。见this answer

你可以阅读Apple's Core image Filter参考,看看iOS中支持哪些过滤器,但坏消息是转换没有成为iOS 5的削减。在iOS 5中唯一可用于处理合成的过滤器是CISourceOverCompositing,对你来说可能不是很有趣。

答案 1 :(得分:1)

Apple WWDC 2014会议“Core Image的进展”列出了iOS中提供的115个CIF过滤器。截至2014年,CIDissolveTransition被列为支持。见会议514 https://developer.apple.com/videos/play/wwdc2014/514/ 再试一次!

答案 2 :(得分:0)

正如Jay在回答中提到的,iOS不支持转换。但是,我找到并编辑了一个脚本,它抓取两个图像的像素值,并根据百分比返回两个图像的交叉。这是方法:

- (UIImage*)morphImage:(UIImage*)img1
             withImage:(UIImage*)img2
             withValue:(float)val
{  
CGImageRef sourceImage = img1.CGImage;
CGImageRef sourceImage2 = img2.CGImage;

CFDataRef theData;
theData = CGDataProviderCopyData(CGImageGetDataProvider(sourceImage));
CFDataRef theData2;
theData2 = CGDataProviderCopyData(CGImageGetDataProvider(sourceImage2));

UInt8 *pixelData = (UInt8 *) CFDataGetBytePtr(theData);
UInt8 *pixelData2 = (UInt8 *) CFDataGetBytePtr(theData2);

int dataLength = CFDataGetLength(theData);

//color byte increments
int red = 0;
int green = 1;
int blue = 2;
//temporary rgb values for both images
int r1, g1, b1, r2, g2, b2;
//fake slider value
for (int index = 0; index < dataLength; index += 4) {
r1 = pixelData[index + red];
g1 = pixelData[index + green];
b1 = pixelData[index + blue];
r2 = pixelData2[index + red];
g2 = pixelData2[index + green];
b2 = pixelData2[index + blue];

pixelData[index + red] += (r2 - r1) * val;
pixelData[index + green] += (g2 - g1) * val;
pixelData[index + blue] += (b2 - b1) * val;
}

CGContextRef context;
context = CGBitmapContextCreate(pixelData,
                              CGImageGetWidth(sourceImage),
                              CGImageGetHeight(sourceImage),
                              8,
                              CGImageGetBytesPerRow(sourceImage),
                              CGImageGetColorSpace(sourceImage),
                              kCGImageAlphaPremultipliedLast);

CGImageRef newCGImage = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:newCGImage];

CGContextRelease(context);
CFRelease(theData);
CGImageRelease(newCGImage);

return newImage;

}

我没有在设备上测试它,但是当使用滑块在6到10个200x200图像循环时,它在模拟器上运行得非常流畅。我想通过预先提取图像像素数据可以更有效。