2011-12-16 16 views
22

De acuerdo con la documentación que debe apoyar borrosa, tenga en cuenta la "Disponible en iOS 5.0 y posterior":¿Admite iOS 5 los accesorios CoreImage?

CIFilter Class Reference

Pero de acuerdo con el dispositivo, no lo hace:

[CIFilter filterNamesInCategory:kCICategoryBlur]; 

retornos nada.

acuerdo con las siguientes sólo estos filtros están disponibles en el iPhone y el simulador (que son a la vez funcionando 5.0):

[CIFilter filterNamesInCategory:kCICategoryBuiltIn] 

CIAdditionCompositing, 
CIAffineTransform, 
CICheckerboardGenerator, 
CIColorBlendMode, 
CIColorBurnBlendMode, 
CIColorControls, 
CIColorCube, 
CIColorDodgeBlendMode, 
CIColorInvert, 
CIColorMatrix, 
CIColorMonochrome, 
CIConstantColorGenerator, 
CICrop, 
CIDarkenBlendMode, 
CIDifferenceBlendMode, 
CIExclusionBlendMode, 
CIExposureAdjust, 
CIFalseColor, 
CIGammaAdjust, 
CIGaussianGradient, 
CIHardLightBlendMode, 
CIHighlightShadowAdjust, 
CIHueAdjust, 
CIHueBlendMode, 
CILightenBlendMode, 
CILinearGradient, 
CILuminosityBlendMode, 
CIMaximumCompositing, 
CIMinimumCompositing, 
CIMultiplyBlendMode, 
CIMultiplyCompositing, 
CIOverlayBlendMode, 
CIRadialGradient, 
CISaturationBlendMode, 
CIScreenBlendMode, 
CISepiaTone, 
CISoftLightBlendMode, 
CISourceAtopCompositing, 
CISourceInCompositing, 
CISourceOutCompositing, 
CISourceOverCompositing, 
CIStraightenFilter, 
CIStripesGenerator, 
CITemperatureAndTint, 
CIToneCurve, 
CIVibrance, 
CIVignette, 
CIWhitePointAdjust 
+2

La documentación dice que la constante 'kCICategoryBlur' está disponible, que es. Lo usaste con éxito en '[CIFilter filterNamesInCategory: kCICategoryBlur];'. Lo que le dijo que no había filtros de desenfoque disponibles en ese momento. – idz

+1

@idz Eso me hizo reír, ¡gracias! – lms

Respuesta

5

Por desgracia, no es compatible con ningún borrones. Para eso, tendrás que hacer tu propio.

23

También me decepcionó encontrar que Core Image en iOS no es compatible con desenfoques. Aquí está la función que escribí para hacer un desenfoque Gaussiano de 9 golpes en un UIImage. Llámalo repetidamente para obtener desenfoques más intensos.

@interface UIImage (ImageBlur) 
- (UIImage *)imageWithGaussianBlur9; 
@end 

@implementation UIImage (ImageBlur) 
- (UIImage *)imageWithGaussianBlur9 { 
    float weight[5] = {0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162}; 
    // Blur horizontally 
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); 
    [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]]; 
    for (int x = 1; x < 5; ++x) { 
     [self drawInRect:CGRectMake(x, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]]; 
     [self drawInRect:CGRectMake(-x, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]]; 
    } 
    UIImage *horizBlurredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    // Blur vertically 
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); 
    [horizBlurredImage drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]]; 
    for (int y = 1; y < 5; ++y) { 
     [horizBlurredImage drawInRect:CGRectMake(0, y, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]]; 
     [horizBlurredImage drawInRect:CGRectMake(0, -y, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]]; 
    } 
    UIImage *blurredImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    // 
    return blurredImage; 
} 

a llamarlo en una imagen existente como esto:

UIImage *blurredImage = [originalImage imageWithGaussianBlur9]; 

y repetirlo para obtener difuminación más fuerte, así:

blurredImage = [blurredImage imageWithGaussianBlur9]; 
+5

Gran solución de baja dependencia –

25

Una vez más, en un intento de salvar a todos iOS blur isses, aquí está mi contribución:

https://github.com/tomsoft1/StackBluriOS

Una biblioteca de desenfoque simple basada en Stack Blur. Pila falta de definición es muy similar a gaussiano, pero mucho más rápido (ver http://incubator.quasimondo.com/processing/fast_blur_deluxe.php)

utilizar de esta manera:

UIImage *newIma=[sourceIma stackBlur:radius] 

Esperanza esta ayuda

+0

Implementé la mía y la aplicación ya está en la tienda de aplicaciones, pero lo tendré en cuenta para futuras consultas. ¡Gracias por el consejo! – lms

+0

El StackBlur iOS gira la imagen 90 grados. Creo que debería arreglarse – ppaulojr

+0

@ppaulojr ¿Estás seguro del problema de la rotación? Debería mantener todos los demás parámetros idénticos. Si aún tiene el problema, proporcione una imagen de muestra que tenga el problema con el código de prueba – tomsoft

31

filtros Mientras Core imagen en IOS 5.0 carece de falta de definición, hay sigue siendo una forma de obtener imágenes borrosas aceleradas por GPU de imágenes y video. Mi marco de código abierto GPUImage tiene varios tipos de desenfoque, incluido Gaussian (utilizando GPUImageGaussianBlurFilter para un gaussiano general o GPUImageFastBlurFilter para un gaussiano de hardware optimizado para 9), cuadro (usando un GPUImageBoxBlurFilter), mediana (usando un GPUImageMedianFilter) y un desenfoque bilateral (usando un GPUImageBilateralBlurFilter).

Describo los sombreadores utilizados para quitar el desenfoque gaussiano optimizado para hardware en this answer, y puede examinar el código que uso para el resto dentro del marco. Estos filtros se ejecutan decenas de veces más rápido que cualquier otra rutina de CPU que haya intentado.

También he incorporado estos desenfoques en efectos de procesamiento de varias etapas, como enmascaramiento de enfoque, filtrado de desplazamiento de inclinación, detección de bordes de Canny y detección de esquina de Harris, todos los cuales están disponibles como filtros dentro de este marco.

+0

+1 parece una gran biblioteca – lms

+0

Brad, eres increíble la biblioteca es simplemente increíble! Es una pena que no puedo votar más de una vez. – Raspu

4

ACTUALIZACIÓN: A partir de iOS 6 [CIFilter filterNamesInCategory:kCICategoryBlur]; devuelve CIGaussianBlur lo que significa que este filtro está disponible en el dispositivo. Aunque esto es cierto, usted (probablemente) obtendrá un mejor rendimiento y más flexibilidad con GPUImage.

+0

He encontrado que el desenfoque CIFilter es muy inestable. Ocasionalmente, causa un bloqueo extremadamente extraño en mi iPad que bloquea la pantalla, pero puedo decir que el iPad sigue siendo funcional porque puedo escuchar el sonido cuando responde a los toques. Tengo que restablecerme para arreglarlo. De todos modos, el reemplazo directo por John Stephan anterior fue una gran solución. –

0

Si puede utilizar OpenGL ES en su aplicación para iOS, esta es la forma de calcular la mediana en un radio de vecindad de píxeles de su elección (el medio es de un tipo de desenfoque, por supuesto):

kernel vec4 medianUnsharpKernel(sampler u) { 
vec4 pixel = unpremultiply(sample(u, samplerCoord(u))); 
vec2 xy = destCoord(); 
int radius = 3; 
int bounds = (radius - 1)/2; 
vec4 sum = vec4(0.0); 
for (int i = (0 - bounds); i <= bounds; i++) 
{ 
    for (int j = (0 - bounds); j <= bounds; j++) 
    { 
     sum += unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j))))); 
    } 
} 
vec4 mean = vec4(sum/vec4(pow(float(radius), 2.0))); 
float mean_avg = float(mean); 
float comp_avg = 0.0; 
vec4 comp = vec4(0.0); 
vec4 median = mean; 
for (int i = (0 - bounds); i <= bounds; i++) 
{ 
    for (int j = (0 - bounds); j <= bounds; j++) 
    { 
     comp = unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j))))); 
     comp_avg = float(comp); 
     median = (comp_avg < mean_avg) ? max(median, comp) : median; 
    } 
} 

return premultiply(vec4(vec3(abs(pixel.rgb - median.rgb)), 1.0)); 
} 

Una breve descripción de los pasos 1. Calcule la media de los valores de los píxeles que rodean el píxel fuente en una vecindad de 3x3; 2. Encuentra el valor máximo de píxeles de todos los píxeles en el mismo vecindario que son menores que la media. 3. [OPCIONAL] Reste el valor de píxel mediano del valor del píxel de origen para la detección de bordes.

Si está utilizando el valor mediano para la detección de bordes, hay un par de maneras de modificar el código anterior para obtener mejores resultados, a saber, filtrado medio híbrido y filtrado de medios truncados (un sustituto y un mejor filtrado 'modo') Si estás interesado, por favor pregunta.