How do I create blurred text in an iPhone view?

后端 未结 4 1971
小蘑菇
小蘑菇 2020-12-16 05:30

I am building up a view with various text and image elements.

I want to display some text in the view with a blurry copy of the text behind it, but not just a text s

相关标签:
4条回答
  • 2020-12-16 06:08

    You will take a performance hit if you use alpha layers. Consider a different approach if possible (maybe even precompositing the text and flattening it into a graphic instead of multiple layers).

    Try it, and use Instruments to check out the performance and see if it's acceptable. If you're doing it in a scrolling view, your scrolling will bog down a lot.

    0 讨论(0)
  • 2020-12-16 06:11

    Take a look at Apple's GLImageProcessing iPhone sample. It does some blurring, among other things.

    The relevant code includes:

    static void blur(V2fT2f *quad, float t) // t = 1
    {
        GLint tex;
        V2fT2f tmpquad[4];
        float offw = t / Input.wide;
        float offh = t / Input.high;
        int i;
    
        glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);
    
        // Three pass small blur, using rotated pattern to sample 17 texels:
        //
        // .\/.. 
        // ./\\/ 
        // \/X/\   rotated samples filter across texel corners
        // /\\/. 
        // ../\. 
    
        // Pass one: center nearest sample
        glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
        glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glColor4f(1.0/5, 1.0/5, 1.0/5, 1.0);
        validateTexEnv();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
        // Pass two: accumulate two rotated linear samples
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE);
        for (i = 0; i < 4; i++)
        {
            tmpquad[i].x = quad[i].s + 1.5 * offw;
            tmpquad[i].y = quad[i].t + 0.5 * offh;
            tmpquad[i].s = quad[i].s - 1.5 * offw;
            tmpquad[i].t = quad[i].t - 0.5 * offh;
        }
        glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].x);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glActiveTexture(GL_TEXTURE1);
        glEnable(GL_TEXTURE_2D);
        glClientActiveTexture(GL_TEXTURE1);
        glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].s);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glBindTexture(GL_TEXTURE_2D, tex);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_INTERPOLATE);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PREVIOUS);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,         GL_PRIMARY_COLOR);
        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,     GL_SRC_COLOR);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_PRIMARY_COLOR);
    
        glColor4f(0.5, 0.5, 0.5, 2.0/5);
        validateTexEnv();
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
        // Pass three: accumulate two rotated linear samples
        for (i = 0; i < 4; i++)
        {
            tmpquad[i].x = quad[i].s - 0.5 * offw;
            tmpquad[i].y = quad[i].t + 1.5 * offh;
            tmpquad[i].s = quad[i].s + 0.5 * offw;
            tmpquad[i].t = quad[i].t - 1.5 * offh;
        }
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
        // Restore state
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glClientActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, Half.texID);
        glDisable(GL_TEXTURE_2D);
        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,     GL_SRC_ALPHA);
        glActiveTexture(GL_TEXTURE0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glDisable(GL_BLEND);
    }
    
    0 讨论(0)
  • 2020-12-16 06:11

    On the desktop, no question, you'd use CoreImage to do this.

    On the phone though, I don't think there exists a way to do this using CoreGraphics. If it is absolutely critical OpenGLES may be able to help.

    However, I would suggest rethinking your interface. I would think the blurred text would be distracting.

    Edit: mledford points out in the comments that you could use CoreAnimation. I don't know if CA on the phone includes blur radius like on the desktop, but you could try it.

    0 讨论(0)
  • 2020-12-16 06:16

    iPhone OS doesn't provide any Core Image filters that I know of - otherwise, yes, a filtered CALayer would be the right way to do it. If NSBitmapImageRep were available, you could do a primitive blur by drawing the text to it, shrinking the image (downsampling), then enlarging the image again (upsampling) - unfortunately it seems to be missing as well. I've seen blurred text accomplished in Flash, which (last I checked) doesn't have pixel-level filtering; you might try looking for a tutorial on that and seeing what you can adapt to Cocoa Touch.

    0 讨论(0)
提交回复
热议问题