首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最大图像大小在CIFilter / CIKernel?

最大图像大小在CIFilter / CIKernel?
EN

Stack Overflow用户
提问于 2010-10-06 16:37:07
回答 1查看 2.2K关注 0票数 3

有人知道自定义CIFilters对图像大小的限制吗?我已经创建了一个过滤器,当图像达到2兆像素时,它会像预期的那样执行,但是当图像变大时,会产生非常奇怪的结果。我已经测试了这两个在我的可可应用程序以及石英作曲家。我开发的滤波器是一个几何型失真滤波器,它(我认为)需要一个ROI和一个跨越整个输入图像的DOD。我已经创建了这个过滤器,以重新映射全景图像,所以我想这个工作在非常大(50-100兆像素)图像。

作为一个简单的测试,考虑下面的CIFilter (可以在Quartz Composer中使用),它只翻译图像的左下角,以便将图像的左下角转换到中心(我知道这可以通过仿射变换完成,但我需要在更复杂的过滤器中执行这样的操作)。当图像为2000x1000时,此过滤器可以正常工作,但当输入图像为4000x2000像素时,会产生奇怪的结果。问题是,要么转换不准确地将拐角移到中心,要么图像输出完全消失。我注意到在大图像上使用更复杂的过滤器的其他奇怪问题,但我认为这个简单的过滤器说明了我的问题,可以在Quartz Composer中复制。

代码语言:javascript
复制
kernel vec4 equidistantProjection(sampler src, __color color)
{
     vec2 coordinate = samplerCoord(src);
     vec2 result;
     vec4 outputImage;

     result.x = (coordinate.x - samplerSize(src).x / 2.0);
     result.y = (coordinate.y - samplerSize(src).y / 2.0);

     outputImage = unpremultiply(sample(src,result));

     return premultiply(outputImage);
}

当使用工作坐标而不是采样坐标时,也会出现相同的奇怪行为,但在这种情况下,大小为2000x1000的图像会出现错误,但对于大小为1000x500的图像则会发生错误。

代码语言:javascript
复制
kernel vec4 equidistantProjection(sampler src, __color color, vec2 destinationDimensions)
{
     vec2 coordinate = destCoord();
     vec2 result;
     vec4 outputImage;

     result.x = (coordinate.x - destinationDimensions.x / 2.0);
     result.y = (coordinate.y - destinationDimensions.y / 2.0);

     outputImage = unpremultiply(sample(src,result));
     outputImage = unpremultiply(sample(src,samplerTransform(src, result)));

     return premultiply(outputImage);
}

作为参考,我在过滤器的- (CIImage *)outputImage方法的目标-C部分中添加了以下内容,将DOD设置为整个输入图像。

代码语言:javascript
复制
- (CIImage *)outputImage
{
    CISampler *src = [CISampler samplerWithImage: inputImage];



     NSArray * outputExtent = [NSArray arrayWithObjects:
            [NSNumber numberWithInt:0],
            [NSNumber numberWithInt:0],
            [NSNumber numberWithFloat:[inputImage extent].size.width],
            [NSNumber numberWithFloat:[inputImage extent].size.height],nil];


return [self apply: filterKernel, src, inputColor, zoom, viewBounds, inputOrigin,
     kCIApplyOptionDefinition, [src definition], kCIApplyOptionExtent, outputExtent, nil];

}

此外,我还添加了以下方法来设置我在- (id)init方法中使用以下方法调用的ROI:[filterKernel setROISelector:@selector(regionOf:destRect:userInfo:)];

代码语言:javascript
复制
- (CGRect) regionOf:(int)samplerIndex destRect:(CGRect)r userInfo:obj
{

     return r;
}

如能在此问题上提供任何帮助或建议,将不胜感激。我确信CIFilters可以处理更大的图像,因为我使用了超过5000万像素的CIBumpDistortion,所以我肯定做错了什么。有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2010-11-01 11:00:00

通过使用CoreImage,我发现它可以将大图像切割成各个部分。例如,在您的示例中,4kx2k图像可以拆分为42kx1k图像并单独呈现。不幸的是,这种优化技巧影响了samplerCoord,一些依赖于坐标的过滤器在大图像上不正确地工作。

我的解决方案是使用destCoord而不是samplerCoord。当然,您应该记住,可以在非零原点和destCoord中呈现图像。我编写了自己的过滤器,因此我能够将整个范围作为vec4参数传递。

示例:尝试使用CIFilter生成图像,如下所示:

代码语言:javascript
复制
float gray = (samplerCoord.x / samplerSize.width) * (samplerCoord.y / samplerSize.height);

这个输出应该给我们黑色(0,0)和白色(1,1),对吗?然而,对于大图像,你会看到很少的四边形,而不是一个单一的梯度。这是由于来自CoreImage引擎的优化呈现,我还没有找到一种方法来传递它,但是您可以这样重写内核:

代码语言:javascript
复制
float gray = ((destCoord.x - rect.x) / rect.size) * ((destCoord.y - rect.y) / rect.height)

其中rect是取样器的真实范围,您必须通过。为此,我使用了inputImage扩展,但它依赖于过滤器,在您的情况下可以是其他的。

希望这个解释清楚了。购买方式,它看起来就像系统内核工作只是很好,即使是大的图像,所以你应该担心这个技巧在您的自定义内核只。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3874833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档