首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义CIKernel位移图

自定义CIKernel位移图
EN

Stack Overflow用户
提问于 2015-09-14 22:50:42
回答 2查看 761关注 0票数 5

我正试图为iOS 8创建一个位移映射create,它将像素水平地从映射R通道转移到垂直移动的G通道。必须相对于源图像大小mapPixel =((dest.x/ source e.Width)* map.width,(dest.y / source.height) * map.height)选择映射像素坐标。

我测试的输入图像大小是2048x2048,地图是红绿珀林噪声2560x2560。

在Quartz Composer中,cikernel的工作原理几乎与预期的一样,只是映射没有应用于整个图像。

代码语言:javascript
复制
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);
}

下面是过滤器函数的样子:

代码语言:javascript
复制
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中的样子

代码语言:javascript
复制
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是错的,采样器是平铺的,但我搞不懂。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-16 20:38:47

事实证明,内核是错误的。这里有一个内核来完成这项工作

代码语言:javascript
复制
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);
}
票数 1
EN

Stack Overflow用户

发布于 2022-05-10 09:28:20

这是与Metal相同的代码

代码语言:javascript
复制
#include <metal_stdlib>
using namespace metal;
#include <CoreImage/CoreImage.h>

extern "C" {
  namespace coreimage {
    float4 displaceFilterKernel(sampler source, sampler map, float scaleX, float scaleY)
    {
      float2 d = map.coord();
      float4 mapPixel = map.sample(d);
      float shiftX = ((mapPixel.x * 2.0) - 1.0) * scaleX;
      float shiftY = ((mapPixel.y * 2.0) - 1.0) * scaleY;
      float2 s = float2(d.x, 1.0 - d.y) + float2(shiftX, shiftY);
      return sample(source, s);
    }
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32575127

复制
相关文章

相似问题

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