«Настоящий» эффект джинна, реализованный в Mac OS X, представляет собой нелинейное преобразование исходного изображения. Один из способов реализовать это - использовать фильтры Core Image (которые являются частными / недокументированными на iOS, но доступны на Mac).
Вы пишете фильтр с параметром 'time'. Для каждого значения параметра времени в данном временном интервале (скажем, {0,2}) вам необходимо определить исходную координату для каждой целевой координаты на изображении. Если исходная координата выходит за границы, установите альфа на ноль, иначе верните значение входного изображения с исходной координатой.
kernel vec4 ASGenieKernel(sampler src, float t, float D, float ytarget) {
vec2 takeFrom; // In destination coordinates.
vec2 original = samplerCoord(src);
vec2 size;
float g, t2, a;
vec4 c;
size = samplerSize(src);
t2 = compare(t-1.0,t,1.0);
takeFrom.x = original.x + compare(t-1.0,0.0,1.0)*size.x*(t-1.0);
a = compare(takeFrom.x, 0.0, 1.0);
a = compare(a-0.5,0.0,compare(takeFrom.x-size.x, 1.0, 0.0));
// Apply an envelope. This is where non-linearity is introduced.
t2 = t2 * (1.0 - tan_(1.57*original.x/size.x - 0.78539))*0.5;
g = 1.0 - D / size.y;
takeFrom.y = (original.y - t2*ytarget*g)/(1.0-t2*g);
a = compare(a-0.5,0.0,compare(takeFrom.y, 0.0, 1.0));
a = compare(a-0.5,0.0,compare(takeFrom.y-size.y, 1.0, 0.0));
takeFrom.x = compare(takeFrom.x, 0.0, takeFrom.x);
takeFrom.x = compare(takeFrom.x-size.x, takeFrom.x, 0.0);
takeFrom.y = compare(takeFrom.y, 0.0, takeFrom.y);
takeFrom.y = compare(takeFrom.y-size.y, takeFrom.y, 0.0);
c = sample(src, takeFrom);
c.w = a;
return c; }
У меня есть сообщение в блоге с некоторыми подробностями и проектом Quartz Composer: Сообщение в блоге Genie Effect