自定义CIKernel置换贴图

时间:2015-09-14 22:50:43

标签: ios objective-c swift core-image cifilter

我正在尝试为iOS 8创建一个置换贴图cikernel,它将像素从地图R通道水平移动,并从G通道垂直移动。 必须相对于源图像大小拾取地图像素坐标mapPixel =((dest.x / source.width)* map.width,(dest.y / source.height)* map.height)

我测试的输入图像尺寸是2048 x 2048 而地图是红绿色的柏林噪音2560 x 2560

在Quartz Composer中,cikernel几乎按预期工作,除了地图未应用于整个图像

kernel vec4 coreImageKernel(sampler image, sampler displaceMap, float scaleX, float scaleY)
{
 vec2 destination = destCoord();

 vec2 imageSize = samplerSize(image);
 float xPercent = destination.x / imageSize.x;
 float yPercent = destination.y / imageSize.y;

 vec2 mapSize = samplerSize(displaceMap);
 vec2 mapCoord = vec2(mapSize.x * xPercent, mapSize.y * yPercent);

 vec4 mapPixel = sample(displaceMap, mapCoord);
 float ratioShiftX = ((mapPixel.x) * 2.0) - 1.0;
 float ratioShiftY = ((mapPixel.y) * 2.0) - 1.0;
 vec2 pixelShift = vec2(ratioShiftX * scaleX, ratioShiftY * scaleY);

 return sample(image, destination - pixelShift);
}

这是过滤器功能的样子:

function __image main(__image image, __image displaceMap, __number scaleX, __number scaleY) {
  return coreImageKernel.apply(image.definition, null, image, displaceMap, scaleX, scaleY);
}

但是当我在CIFilter中加载cikernel时,结果远非我在Quartz Composer中看到的结果。 这是我的应用函数在CIFilter中的样子

override var outputImage:CIImage? {
    if let inputImage = inputImage {
        if let inputMap = inputMap {
            let args = [inputImage as AnyObject, inputMap as AnyObject, inputScaleX, inputScaleY]

            return CIDisplacementMapFilter.kernel?.applyWithExtent(inputImage.extent, roiCallback: {
                    (index, rect) in

                    if index == 0 {
                        return rect
                    }

                    return CGRectInfinite
                }, arguments: args)
        }
    }

    return nil
}

我猜测投资回报率是错误的,采样器是平铺的,但我无法弄明白。

1 个答案:

答案 0 :(得分:1)

事实证明内核是错误的。 这是一个完成工作的内核

kernel vec4 displace(sampler source, sampler map, float scaleX, float scaleY)
{

vec2 d = destCoord();
vec4 mapPixel = sample(map, samplerTransform(map, d));
float shiftX = ((mapPixel.x * 2.0) - 1.0) * scaleX;
float shiftY = ((mapPixel.y * 2.0) - 1.0) * scaleY;

vec2 s = samplerTransform(source, d + vec2(shiftX, shiftY));

return sample(source, s);
}