我正在尝试创建一个位移映射CIKernel,用于iOS 8,该映射将像素从地图R通道水平移动和从G通道垂直移动。
必须相对于源图像大小选择地图像素坐标mapPixel = ((dest.x / source.width) * map.width, (dest.y / source.height) * map.height)
我测试的输入图像大小为2048 x 2048, 地图是红绿柏林噪声2560 x 2560
在Quartz Composer中,cikernel几乎按预期工作,只是未将地图应用于整个图像。
我测试的输入图像大小为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);
}
这是 filter 函数的样子:
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
}
我猜测ROI是错误的,采样器是平铺的,但我无法弄清楚。