Как создать размытый текст в представлении iPhone? - PullRequest
7 голосов
/ 22 октября 2008

Я создаю представление с различными элементами текста и изображения.

Я хочу отобразить некоторый текст в представлении с размытой копией текста позади него, но не просто текстовую тень.

Как мне применить размытый гауссовский текст к UIImage или слою?

Ответы [ 4 ]

9 голосов
/ 10 августа 2009

Взгляните на образец Apple GLImageProcessing для iPhone. Это делает некоторые размытия, между прочим.

Соответствующий код включает в себя:

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);
}
1 голос
/ 23 октября 2008

iPhone OS не предоставляет никаких известных мне фильтров Core Image - иначе да, отфильтрованный CALayer был бы правильным способом сделать это. Если бы NSBitmapImageRep был доступен, вы могли бы сделать примитивное размытие, рисуя к нему текст, сжимая изображение (понижающая дискретизация), а затем снова увеличивая изображение (повышающая дискретизация) - к сожалению, оно, похоже, отсутствует. Я видел размытый текст, выполненный во Flash, который (последний раз я проверял) не имеет фильтрации на уровне пикселей; вы можете попытаться найти учебник по этому вопросу и посмотреть, что вы можете адаптировать к Cocoa Touch.

0 голосов
/ 22 ноября 2008

Вы получите удар по производительности, если будете использовать альфа-слои. Если возможно, рассмотрите другой подход (возможно, даже предварительно скомпонуйте текст и сведите его в графическое изображение вместо нескольких слоев).

Попробуйте и используйте инструменты, чтобы проверить производительность и посмотреть, приемлемо ли это. Если вы делаете это в режиме прокрутки, ваша прокрутка замедлит лот .

0 голосов
/ 23 октября 2008

На рабочем столе, без вопросов, вы бы использовали CoreImage для этого.

Хотя по телефону я не думаю, что существует способ сделать это с помощью CoreGraphics. Если это абсолютно важно, OpenGLES может помочь.

Однако я бы предложил переосмыслить ваш интерфейс. Я думаю, что размытый текст будет отвлекать.

Редактировать: Мледфорд указывает в комментариях, что вы можете использовать CoreAnimation. Я не знаю, имеет ли CA на телефоне радиус размытия, как на рабочем столе, но вы можете попробовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...