Add Fisheye effect to images at runtime using Open

2019-03-16 23:16发布

问题:

my situation is that i receive different images from the server onto the iPhone client.

what i need to do is to add a Fisheye effect to those images.

what my hallucination is that i can build a dome object, then attach images to it as they come to me.

if anyone can give me any pointers to the right direction i'll be thankful.

回答1:

Have you tried looking at Paul Bourke's example code for OpenGL? I don't know if it's compatible with OpenGL-ES. Note the feedback about using "glCopyTexSubImage2D instead of doing a slow glReadPixels".

AFAICT, Paul Bourke is doing essentially what you said, creating a distorted grid (your "dome object") to lay the image on. According to this question, that's a good approach.

Updated:

Or, since iPhone's OpenGL-ES supports shaders (at least in some versions), you could get better performance using a plane distortion technique like this. You'd just have to change the formulas for uv.x and uv.y. Then you wouldn't need to be concerned about breaking up the image into a grid of small polygons... you'd have single-pixel resolution for free. :-)

Hm... maybe you need to define what kind of "fisheye" effect you are looking for. Seems there is more than one.

See also this question.

Updated again:

Here is some GLSL code I wrote to do a lens effect in a shader. I believe it's a hemispherical fisheye lens. It runs under WebGL, which uses OpenGL ES, so it should be adaptable for iPhone.

#ifdef GL_ES
precision highp float;
#endif

uniform vec2 resolution;
uniform vec4 mouse;
uniform sampler2D tex0;

// lens
void main(void)
{
    vec2 p = gl_FragCoord.xy / resolution.xy;
    vec2 m = mouse.xy / resolution.xy;
    float lensSize = 0.4;

    vec2 d = p - m;
    float r = sqrt(dot(d, d)); // distance of pixel from mouse

    vec2 uv;
    if (r >= lensSize) {
        uv = p;
    } else {
        // Thanks to Paul Bourke for these formulas; see
        // http://paulbourke.net/miscellaneous/lenscorrection/
        // and .../lenscorrection/lens.c
        // Choose one formula to uncomment:
        // SQUAREXY:
        // uv = m + vec2(d.x * abs(d.x), d.y * abs(d.y));
        // SQUARER:
        uv = m + d * r; // a.k.a. m + normalize(d) * r * r
        // SINER:
        // uv = m + normalize(d) * sin(r * 3.14159 * 0.5);
        // ASINR:
        // uv = m + normalize(d) * asin(r) / (3.14159 * 0.5);
    }

    vec3 col = texture2D(tex0, vec2(uv.x, -uv.y)).xyz;

    gl_FragColor = vec4(col, 1.0);
}

To test this, paste it into ShaderToy in a WebGL-enabled browser. Set input 0 to a texture like http://www.iquilezles.org/apps/shadertoy/presets/tex0.jpg or http://www.iquilezles.org/apps/shadertoy/presets/tex4.jpg

Click the play button, and drag the mouse around on the rendering area. The lens is centered on the mouse pointer.



回答2:

status=MagickImplodeImage(magick_wand, -3);