2012-04-12 40 views
1

在Ray Wenderlich的网站上关注了tutorial,我决定尝试操纵我学到的知识并将其应用于CITransition,特别是CIDissolveTransition。然而,即使在交叉引用了我对苹果公司自己的过滤器文档(我认为,这些文档已经过时,难以置信地难以适应他们自己错综复杂的例子)之后,我似乎无法看到图像出现。这是我到目前为止:如何在Xcode中使用图像转换过滤器?

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应该显示。最终目标是能够通过使用滑块(我只假设可以工作)通过具有这种溶解效果的图像序列来循环,但是我甚至无法得到这个静态图像来显示。任何帮助将不胜感激。

回答

6

您对filterWithName:keysAndValues:的调用正在返回nil,因为iOS不知道如何制作CIDossolveTransition过滤器。 Core Image for iOS不支持Core image for Mac OS的所有过滤器。见this answer

您可以阅读Apple's Core image Filter参考,看看哪些过滤器在iOS的支持,但坏消息是,过渡没有获得晋级为iOS 5在iOS 5中唯一可用的过滤器,用合成涉及的CISourceOverCompositing ,这对你来说可能不是很有趣。

+0

哦,伙计。不能相信我错过了这一点。这只是给这个项目增加了一个很大的障碍。我假设我的下一个最佳解决方案是手动操作我的图像的像素数据。这看起来很具挑战性。谢谢您的帮助! – MyNameIsKo 2012-04-13 16:18:33

+0

这不再是事实。文档目前声明“适用于OS X v10.4及更高版本以及iOS 6.0及更高版本。” – zot 2016-10-02 02:36:19

0

正如周杰伦在他的回答中所提到的,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个200×200的图像时,循环运行在模拟器相当顺利。我想通过事先提取图像像素数据可能会更高效。