web-dev-qa-db-de.com

Schnelle Unschärfe auf iOS

Ich habe Probleme beim Versuch, einen Teil des Bildschirms in meiner iOS-App zu verwischen. Siehe Bild für eine bessere Vorstellung von dem, was ich versuche. 

BlurBox

Nur der Inhalt der "BlurBox" muss unscharf sein, der Rest kann jedoch klar sein. Wenn Sie also die Tabellenansicht betrachten, ist nur der Inhalt unter der BlurBox verschwommen (selbst wenn Sie scrollen). Der Rest würde klar aussehen. 

Mein erster Ansatz bestand darin, UIGraphicsGetImageFromCurrentImageContext() alle .01s aufzurufen, um alle Ebenen unter der BlurBox in einem Bild zusammenzufassen. Dann verwischen Sie das Bild und zeigen Sie es auf alles auf. 

Die Methoden, die ich zum Verwischen versucht habe, sind:

https://github.com/tomsoft1/StackBluriOS

https://github.com/coryleach/UIImageAdjust

https://github.com/esilverberg/ios-image-filters

https://github.com/cmkilger/CKImageAdditions

[layer setRasterizationScale:0.25];
[layer setShouldRasterize:YES];

Sowie ein paar benutzerdefinierte Versuche. Ich habe mir auch Apples GLImageProcessing angeschaut, aber ich denke, es ist ein bisschen übertrieben für das, was ich hier versuche. 

Das Problem ist, dass sie alle toslow sind. Die App ist nicht im App Store verfügbar, daher bin ich offen für die Verwendung von privaten/undokumentierten Frameworks. 

Ich hatte die weit verbreitete Idee, die drawRect-Methode aller Komponenten, die ich verwende (UITableViewCells, UITableView usw.), außer Kraft zu setzen und jede der Komponenten unabhängig voneinander zu verwischen. Dies würde jedoch einige Zeit in Anspruch nehmen, klingt dies sogar nach einer realisierbaren Option? 


UPDATE:

Ich habe versucht, CIFilters wie folgt zu verwenden:

CIImage *inputImage = [[CIImage alloc] initWithImage:[self screenshot]];

CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[blurFilter setDefaults];
[blurFilter setValue: inputImage forKey: @"inputImage"];
[blurFilter setValue: [NSNumber numberWithFloat:10.0f]
                           forKey:@"inputRadius"];


CIImage *outputImage = [blurFilter valueForKey: @"outputImage"];

CIContext *context = [CIContext contextWithOptions:nil];

self.bluredImageView.image = [UIImage imageWithCGImage:[context createCGImage:outputImage fromRect:outputImage.extent]];

Das funktioniert zwar, ist aber unglaublich langsam. :(

Ich sehe, dass einige Implementierungen nur verwischen, wenn ich ein von der Festplatte geladenes Image übergeben habe. Wenn ich ein UIImage weitergebe, das ich mit UIGraphicsGetImageFromCurrentImageContext() erstellt habe, funktioniert es nicht. Irgendwelche Ideen, warum das so wäre?


UPDATE:

Ich habe den Vorschlag des Patels wie folgt ausprobiert:

CALayer *backgroundLayer = [CALayer layer];

CIFilter *blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[blurFilter setDefaults];
backgroundLayer.backgroundFilters = [NSArray arrayWithObject:blurFilter];

[[self.view layer] addSublayer:backgroundLayer];

Es funktioniert jedoch nicht :(


UPDATE SEIT BOUNTY ADDED:

Ich habe es geschafft, die BlurBox mit Hilfe von TomSoft1s Stackblur richtig zum Laufen zu bringen, da er die Möglichkeit hat, ein Bild im RGBA-Format (32 Bit/Pixel) schnell zu normalisieren. Es ist jedoch immer noch ziemlich langsam. 

Ich habe einen Timer, der alle 0.03s ein Update aufruft, um das Bild von dem, was sich unter der BlurBox befindet, zu nehmen, das Bild zu verwischen und auf dem Bildschirm anzuzeigen. Ich brauche Hilfe beim Erhöhen der "fps" auf der BlurBox. 

20
random

Ich würde Brad Larson s GPUImage empfehlen, das vollständig von der GPU für eine Vielzahl von Bildverarbeitungseffekten unterstützt wird. Es ist sehr schnell und sogar schnell genug, dass er in seiner Demo-App Echtzeit-Videobearbeitung von der Kamera aus ausführt und die Bildrate hervorragend ist.

https://github.com/BradLarson/GPUImage

Hier ist ein Codeausschnitt, den ich geschrieben habe, um eine grundlegende Box-Unschärfe anzuwenden, die das untere und obere Drittel des Bildes verwischt, die Mitte des Bildes jedoch unscharf lässt. Seine Bibliothek ist äußerst umfangreich und enthält fast alle erdenklichen Bildfilter-Effekte.

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:[self screenshot]];

GPUImageTiltShiftFilter *boxBlur = [[GPUImageTiltShiftFilter alloc] init];
        boxBlur.blurSize = 0.5;

[stillImageSource addTarget:boxBlur];

[stillImageSource processImage];

UIImage *processedImage = [stillImageSource imageFromCurrentlyProcessedOutput];
41
brynbodayle

Es kann zwar etwas spät sein, um zu antworten, Sie können jedoch Core Image-Filter verwenden. Der Grund, warum es so langsam ist, ist diese Linie.

CIContext *context = [CIContext contextWithOptions:nil];

In den Apple-Dokumenten, um die beste Leistung in Core Image zu erzielen, werden sie zunächst angegeben

"Erstellen Sie nicht jedes Mal ein CIContext-Objekt, wenn Sie rendern . Kontexte speichern viele Statusinformationen;

Meine persönliche Lösung dafür ist, ein Singleton für den Core Image Context zu erstellen. Also erstelle ich immer nur eine.

Mein Code befindet sich in diesem Demo-Projekt auf GitHub.

https://github.com/KyleLopez/DemoCoreImage

Fühlen Sie sich frei, es zu verwenden, oder finden Sie eine andere Lösung, die Ihren Wünschen entspricht. Der langsamste Teil, den ich in CoreImage gefunden habe, ist der Kontext. Die Bildverarbeitung danach ist sehr schnell.

7
Kyle

Ich habe dies nicht getestet, aber ich frage mich, ob Sie eine CALayer an der Stelle platzieren möchten, an der Sie die Box verwischen möchten, und dann eine nützliche CIFilter finden, die Sie in CALayer'sbackgroundFilters einstellen können. Nur ein Gedanke.

Siehe CALayer.backgroundFilters

1
epatel

Möglicherweise versuchen Sie den Apple Core Image Filter (CIFilter) -Satz von Routinen. Sie benötigen iOS 5, daher können Sie sie möglicherweise nicht verwenden. 

Ich bin mir nicht sicher, ob es schneller ist als die Methoden, die Sie ausprobiert haben, aber ich habe es in der Vergangenheit in Projekten verwendet, und es funktioniert wirklich gut. Wenn Sie den Teil des Bildschirms, den Sie unscharf machen möchten, fassen können, diesen in ein Bild einfügen, durch einen Filter führen und ihn dann an der entsprechenden Stelle auf dem Bildschirm erneut anzeigen, sollte dies funktionieren. 

Ich habe die Filter verwendet, um die Farben eines Bildes in Echtzeit zu ändern, und es hat gut funktioniert.

http://developer.Apple.com/library/ios/#DOCUMENTATION/GraphicsImaging/Reference/QuartzCoreFramework/Classes/CIFilter_Class/Reference/Reference.html

0
PaulPerry

Haben Sie diese Bibliothek ausprobiert:

https://github.com/gdawg/uiimage-dsp

Es verwendet das vDSP/Accelerate-Framework und scheint einfach zu verwenden.

BTW: 0.01s scheint viel zu schnell zu sein. 0,03 sollte auch gut sein.

0
Codo