【发布时间】:2022-05-10 17:28:20
【问题描述】:
我正在尝试为 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
}
我猜 ROI 是错误的,采样器是平铺的,但我想不通。
【问题讨论】:
标签: ios objective-c swift core-image cifilter