Поддерживает ли iOS 5 средства нарезки CoreImage? - PullRequest
22 голосов
/ 16 декабря 2011

Согласно документации, она должна поддерживать размытие, обратите внимание на «Доступно в iOS 5.0 и более поздних версиях»:

Справочник по классам CIFilter

Но в зависимости от устройства,это не так:

[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

Ответы [ 8 ]

31 голосов
/ 28 мая 2012

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

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

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

25 голосов
/ 07 февраля 2012

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

https://github.com/tomsoft1/StackBluriOS

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

используйте его так:

UIImage *newIma=[sourceIma stackBlur:radius]

Надеюсь, что эта помощь

24 голосов
/ 18 января 2012

Я тоже был разочарован, обнаружив, что 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 голосов
/ 17 декабря 2011

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

4 голосов
/ 24 мая 2013

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

1 голос
/ 30 января 2013

Вот ссылка на наш учебник по созданию эффекта размытия в приложении для iOS с различными подходами. http://blog.denivip.ru/index.php/2013/01/blur-effect-in-ios-applications/?lang=en

0 голосов
/ 10 июля 2019

Поскольку я использую Xamarin, я преобразовал ответ Джона Стивена в C #:

    private UIImage ImageWithGaussianBlur9(UIImage image)
    {
        var weight = new nfloat[]
        {
            0.2270270270f, 0.1945945946f, 0.1216216216f, 0.0540540541f, 0.0162162162f
        };

        var width = image.Size.Width;
        var height = image.Size.Height;
        // Blur horizontally
        UIGraphics.BeginImageContextWithOptions(image.Size, false, 1f);

        image.Draw(new CGRect(0f, 0f, width, height), CGBlendMode.PlusLighter, weight[0]);

        for (int x = 1; x < 5; ++x)
        {
            image.Draw(new CGRect(x, 0, width, height), CGBlendMode.PlusLighter, weight[x]);
            image.Draw(new CGRect(-x, 0, width, height), CGBlendMode.PlusLighter, weight[x]);
        }

        var horizBlurredImage = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();

        // Blur vertically
        UIGraphics.BeginImageContextWithOptions(image.Size, false, 1f);

        horizBlurredImage.Draw(new CGRect(0, 0, width, height), CGBlendMode.PlusLighter, weight[0]);

        for (int y = 1; y < 5; ++y)
        {
            horizBlurredImage.Draw(new CGRect(0, y, width, height), CGBlendMode.PlusLighter, weight[y]);
            horizBlurredImage.Draw(new CGRect(0, -y, width, height), CGBlendMode.PlusLighter, weight[y]);
        }

        var blurredImage = UIGraphics.GetImageFromCurrentImageContext();
        UIGraphics.EndImageContext();

        return blurredImage;
    }
0 голосов
/ 04 июля 2015

Если вы можете использовать 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. Рассчитать среднее значение значений пикселей, окружающих исходный пиксель в окрестности 3х3; 2. Найдите максимальное значение для всех пикселей в одном районе, которые меньше среднего значения. 3. [ДОПОЛНИТЕЛЬНО] Вычтите значение медианного пикселя из значения исходного пикселя для обнаружения края.

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

...