cocoa-touch ios5 core-image

cocoa touch - ¿Admite iOS 5 los desenfocadores de CoreImage?



cocoa-touch ios5 (7)

De acuerdo con la documentación que debe admitir la borrosidad, tenga en cuenta "Disponible en iOS 5.0 y posterior":

Referencia de clase CIFilter

Pero según el dispositivo, no:

[CIFilter filterNamesInCategory:kCICategoryBlur];

no devuelve nada

De acuerdo con lo siguiente, solo estos filtros están disponibles en mi iPhone y Simulator (que funcionan con 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


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.




Lamentablemente, no admite ninguna falta de definición. Para eso, tendrás que hacer tu propio.


Si bien Core Image en iOS 5.0 carece de filtros de desenfoque, todavía hay una manera de obtener imágenes desenfocadas aceleradas por GPU de imágenes y video. Mi marco de GPUImage código abierto tiene varios tipos de desenfoque, incluido Gaussian (usando GPUImageGaussianBlurFilter para un gaussiano general o GPUImageFastBlurFilter para un gaussiano de 9 impactos optimizado para hardware), cuadro (usando un GPUImageBoxBlurFilter), mediana (usando un GPUImageMedianFilter) y un desenfoque bilateral (usando un GPUImageBilateralBlurFilter).

En esta respuesta , describo los sombreadores utilizados para extraer el desenfoque gaussiano optimizado para hardware 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.


Si puede usar OpenGL ES en su aplicación iOS, así es como calcula la mediana en un radio de vecindad de píxeles de su elección (la mediana es 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 un vecindario de 3x3; 2. Encuentre 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 de píxel fuente para la detección de bordes.

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


También me decepcionó descubrir que Core Image en iOS no admite 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; }

Solo llámalo en una imagen existente como esta:

UIImage *blurredImage = [originalImage imageWithGaussianBlur9];

y repítelo para obtener una borrosidad más fuerte, como esta:

blurredImage = [blurredImage imageWithGaussianBlur9];