Я создаю представление с различными элементами текста и изображений.
Я хочу отображать некоторый текст в представлении с размытой копией текста за ним, а не только текстовую тень.
Как применить размытый текст по Гауссу к UIImage или слою?





На рабочем столе, без сомнения, вы бы использовали CoreImage для этого.
Что касается телефона, я не думаю, что существует способ сделать это с помощью CoreGraphics. Если это абсолютно необходимо, OpenGLES может помочь.
Однако я бы предложил переосмыслить ваш интерфейс. Думаю, размытый текст отвлекает.
Обновлено: mledford указывает в комментариях, что вы можете использовать CoreAnimation. Я не знаю, включает ли CA на телефоне радиус размытия, как на рабочем столе, но вы можете попробовать.
Я должен был проверить. :-( Отрывок из документации по фильтрам свойств CALayer. «Особые соображения. Хотя класс CALayer предоставляет это свойство, Core Image недоступен в iPhone OS. В настоящее время фильтры, доступные для этого свойства, не определены».
iPhone OS не предоставляет никаких известных мне фильтров Core Image - в противном случае, да, отфильтрованный CALayer был бы правильным способом сделать это. Если бы NSBitmapImageRep был доступен, вы могли бы сделать примитивное размытие, нарисовав на нем текст, сжав изображение (понижающая дискретизация), а затем снова увеличив изображение (повышающая дискретизация) - к сожалению, этого тоже нет. Я видел размытый текст, выполненный во Flash, который (в последний раз проверял) не имеет фильтрации на уровне пикселей; вы можете попробовать поискать учебник по этому поводу и посмотреть, что вы можете адаптировать к Cocoa Touch.
Вы получите удар по производительности, если будете использовать альфа-слои. Если возможно, подумайте о другом подходе (возможно, даже предварительно составив текст и сведя его в графику вместо нескольких слоев).
Попробуйте и используйте инструменты, чтобы проверить производительность и посмотреть, приемлемо ли она. Если вы делаете это в режиме прокрутки, ваша прокрутка затянет много.
Взгляните на образец 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);
}
Правильно ли предположить, что можно использовать openGL ES в простом приложении с какао-сенсором, не имея представления openGL ES? Могу ли я использовать openGL только для фильтрации размытия? и записать вывод в UIImage?
Нет, мне кажется, я припоминаю немного EAGLView и glview, пропитанных кодом. Я экспериментирую с кодом, который нашел по следующему URL-адресу, который дает гораздо более приятное размытие, чем приведенный выше код. incubator.quasimondo.com/processing/fast_blur_deluxe.php
Это не быстро, но если вам это нужно только для размытия UILabels или текста, это может сработать довольно хорошо.
Колин, не могли бы вы также использовать слои Core Animation для создания этого? Не то чтобы я рекомендовал это ... создавая слой с фильтром размытия, а затем наложив еще один слой поверх?