I feel like I'm missing something really simple. I've got the simplest possible CIKernel, it looks like this:
extern "C" float4 Simple(coreimage::sampler s) {
float2 current = s.coord();
float2 anotherCoord = float2(current.x + 1.0, current.y);
float4 sample = s.sample(anotherCoord); // s.sample(current) works fine
return sample;
}
It's (in my mind) incrementing the x position of the sampler by 1 and sampling the neighboring pixel. What I get in practice is a bunch of banded garbage (pictured below.) The sampler seems to be pretty much undocumented, so I have no idea whether I'm incrementing by the right amount to advance one pixel. The weird banding is still present if I clamp anootherCoord
to s.extent()
. Am I missing something really simple?
The coordinates of coreimage:sampler
are relative, between 0 and 1, where [0,0]
is the lower left corner of the image and [1,1]
is the upper right. So when you add 1.0
to that, you are effectively sampling outside the defined image space.
Core Image provides access to the coreimage:destination
to get absolute coordinates (pixels). Simply add a destination as the last parameter to your kernel function (no need to pass anything when you invoke the kernel with apply
):
extern "C" float4 Simple(coreimage::sampler s, coreimage::destination dest) {
float2 current = dest.coord();
float2 anotherCoord = current + float2(1.0, 0.0);
float4 sample = s.sample(s.transform(anotherCoord));
return sample;
}
dest.coord()
gives you the coordinates in absolute (pixel) space, and s.transform
translates it back into (relative) sampler space.