2011-12-16 2 views
22

Согласно документации, она должна поддерживать размытость, обратите внимание на «Доступно в прошивкой 5.0 и позже»:Поддерживает ли iOS 5 размытие элементов CoreImage?

CIFilter Class Reference

Но в соответствии с устройством, он не делает:

[CIFilter filterNamesInCategory:kCICategoryBlur]; 

возвращается ничего.

В соответствии со следующими только эти фильтры доступны на моем iPhone и Simulator (которые оба работает 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

В документации указано, что существует константа 'kCICategoryBlur', какая она есть. Вы успешно использовали его в '[CIFilter filterNamesInCategory: kCICategoryBlur];'. Который сказал вам, что в то время не было фильтров размытия. – idz

+1

@idz Это заставило меня рассмеяться, спасибо! – lms

ответ

5

К сожалению, он не поддерживает размытости. Для этого вам придется сворачивать самостоятельно.

23

Я тоже был разочарован, обнаружив, что Core Image в iOS не поддерживает размытия. Вот функция, которую я написал, чтобы сделать размытие Гаусса с 9 касанием на UIImage. Назовите его повторно, чтобы получить более сильные размытия.

@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; 
} 

Просто позвоните его на существующем изображении, как это:

UIImage *blurredImage = [originalImage imageWithGaussianBlur9]; 

и повторить его, чтобы получить более сильное размывание, как это:

blurredImage = [blurredImage imageWithGaussianBlur9]; 
+5

Отличное решение с низкой зависимостью –

25

Опять же, в попытке сохранить все iOS blur isses, вот мой вклад:

https://github.com/tomsoft1/StackBluriOS

Простая библиотека размытия, основанная на размытии стека. Стек Размытие очень похоже на Gaussian Blur, но гораздо быстрее (см http://incubator.quasimondo.com/processing/fast_blur_deluxe.php)

использовать его как это:

UIImage *newIma=[sourceIma stackBlur:radius] 

Надежда этой помощь

+0

Я реализовал свое приложение, и приложение уже находится в магазине приложений, но я буду помнить об этом в будущем. Спасибо за совет! – lms

+0

StackBlur iOS поворачивает изображение на 90 градусов. Я думаю, что это должно быть исправлено – ppaulojr

+0

@ppaulojr вы уверены в проблеме вращения? Он должен сохранять все остальные параметры идентичными. Если у вас все еще есть проблема, укажите образец изображения, у которого есть проблема с тестовым кодом. – tomsoft

31

Хотя ядро ​​изображение на прошивке 5.0 не хватает смазанности фильтров, там по-прежнему является способом получения размытых графических изображений и видео. Мой открытый исходный код GPUImage framework имеет несколько типов размытия, включая гауссовский (с использованием GPUImageGaussianBlurFilter для общего гауссова или GPUImageFastBlurFilter для аппаратно-оптимизированного 9-ударного гаусса), поле (с использованием GPUImageBoxBlurFilter), медиана (с использованием GPUImageMedianFilter) и двустороннее размытие (с использованием GPUImageBilateralBlurFilter).

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

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

+0

+1 выглядит как отличная библиотека – lms

+0

Брэд, вы потрясаете, библиотека просто потрясающая! позор, который я не могу проголосовать более одного раза. – Raspu

4

UPDATE: Начиная с iOS 6 [CIFilter filterNamesInCategory:kCICategoryBlur]; возвращает CIGaussianBlur, что означает, что этот фильтр доступен на устройстве. Несмотря на то, что это правда, вы (вероятно) получите более высокую производительность и большую гибкость с помощью GPUImage.

+0

Я обнаружил, что размытость CIFilter очень неустойчива. Иногда это вызывает чрезвычайно странный крах на моем iPad, который блокирует экран, но я могу сказать, что iPad по-прежнему функционирует, потому что я слышу звук, когда он реагирует на прикосновения. Я должен выполнить жесткий сброс, чтобы исправить это. Во всяком случае, замена на замену Джоном Стефаном выше была отличным решением. –

0

Если вы можете использовать OpenGL ES в вашем приложении IOS, это то, как вы вычислить медиану в пиксельном радиусе окрестностей вашего выбора (медиана является типом размытия, конечно):

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)); 
} 

Краткое описание шагов 1. Вычислить среднее значение пикселей, окружающих исходный пиксель, в окрестности 3x3; 2. Найдите максимальное значение пикселя для всех пикселей в том же районе, что меньше среднего. 3. [ДОПОЛНИТЕЛЬНО] Вычтите среднее значение пикселя из значения исходного пикселя для обнаружения края.

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

Смежные вопросы