2013-08-23 30 views
12

Próbuję użyć efektu szkła w stylu iOS 7 w moim szkle, stosując efekty obrazu do zrzutu ekranu MKMapView. This UIImage category, dostarczone przez Apple, jest tym, co używam jako linii bazowej. Metoda ta desaturacji obrazu źródłowego, zastosowanie koloru odcień, i zaciera mocno wykorzystaniem wejściowych Vals:Używanie GPUImage do odtworzenia efektu szkła iOS 7

[image applyBlurWithRadius:10.0 
       tintColor:[UIColor colorWithRed:229/255.0f green:246/255.0f blue:255/255.0f alpha:0.33] 
    saturationDeltaFactor:0.66 
       maskImage:nil]; 

to daje efekt szukam, ale trwa zbyt długo - między .3 i .5 sekund do renderowania na iPhone 4.

enter image description here

chciałbym użyć jako doskonałą GPUImage moich wstępnych prób były około 5-10 razy szybciej, ale ja po prostu nie wydają się uzyskać to prawo.

GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:image]; 

GPUImageSaturationFilter *saturationFilter = [[GPUImageSaturationFilter alloc] init]; 
saturationFilter.saturation = 0.33; // 1.0 - 0.66; 
[stillImageSource addTarget:saturationFilter]; 

GPUImageMonochromeFilter *monochromeFilter = [[GPUImageMonochromeFilter alloc] init]; 
[monochromeFilter setColor:(GPUVector4){229/255.0f, 246/255.0f, 1.0f, 0.33f}]; 
[monochromeFilter setIntensity:0.2]; 
[saturationFilter addTarget:monochromeFilter]; 

GPUImageFastBlurFilter *blurFilter = [[GPUImageFastBlurFilter alloc] init]; 
blurFilter.blurSize = 2; 
blurFilter.blurPasses = 3; 
[monochromeFilter addTarget:blurFilter]; 

[saturationFilter prepareForImageCapture]; 
[monochromeFilter prepareForImageCapture]; 

[stillImageSource processImage]; 
image = [blurFilter imageFromCurrentlyProcessedOutput]; 

Daje to obraz, który jest blisko, ale nie całkiem tam

enter image description here

Rozmycie nie wydaje się być na tyle głęboki, ale gdy próbuję zwiększyć blurSize powyżej, staje się siatkowy, prawie jak kalejdoskop. Możesz zobaczyć siatkę tutaj, powiększając drugi obraz. Odcień koloru, który próbuję naśladować, wydaje się po prostu zmywać obraz zamiast nakładania i mieszania, co, jak sądzę, robi próbka Apple.

Próbowałem ustawić filtry według komentarzy wysłanych przez @BradLarson w another SO question. Czy używam niewłaściwych filtrów GPUImage do odtworzenia tego efektu, czy też po prostu źle je ustawiam?

+0

Czy próbowałeś https://github.com/JagCesar/iOS-blur? Jest świetny, chociaż działa tylko w systemie iOS7. –

+0

iOS-Blur nie jest realnym rozwiązaniem. Nie wiesz, co robi jabłko pod maską, aby to zadziałało, i nie działa na iOS 6. – coneybeare

Odpowiedz

32

OK, pracowałem nad czymś tutaj przez chwilę, a nareszcie mam funkcjonalność. Właśnie wprowadziłem wiele zmian w filtrach rozmycia GPUImage do struktury, i w rezultacie uważam, że mam rozsądną replikę efektu rozmycia Apple, którego używają do takich rzeczy jak widok centrum sterowania.

Wcześniej, plamy, które miałem w ramce, wykorzystywały jeden wstępnie obliczony promień, a jedynym sposobem wpływania na ich intensywność było modyfikowanie odstępów, w których próbkowano piksele od obrazu wejściowego. Przy ograniczonej liczbie próbek na piksel zmiana wielkości wielokrotności odstępu między próbkowanymi pikselami znacznie powyżej 1,5 zaczęła wprowadzać poważne artefakty blokujące, gdy piksele były pomijane.

Nowa metoda rozmycia Gaussa, którą zbudowałem, łączy w sobie zalety wydajności wcześniej obliczonych wag Gaussa z możliwością użycia dowolnego promienia (sigma) dla rozmycia Gaussa. Czyni to, generując shadery w locie, ponieważ są one potrzebne do różnych promieni. Zmniejsza również liczbę próbek tekstur wymaganych dla danego promienia rozmycia, używając interpolacji sprzętowej do odczytu dwóch tekseli na raz dla każdego punktu próbki.

Nowy GPUImageiOSBlurFilter łączy w sobie dostrojony filtr rozmycia Gaussa z dowolnie wybranym promieniem, z filtrem korekcji kolorów, który pojawia się w celu odtworzenia dopasowania, które firma Apple wykonuje w kolorach po ich rozmyciu.Dodałem poniższego porównania do mojej odpowiedzi here, ale pokazuje Apple wbudowanej zacieranie z widoku centrum kontroli po lewej stronie, a mój nowy filtr GPUImage rozmycie po prawej:

Apple's blurGPUImage's blur

jako sposób poprawiania wydajności (rozmycie Apple wydaje się występować z sigmą 48, która wymaga sporego obszaru do próbkowania dla każdego piksela), używam 4-krotnie downsamplingu przed rozmyciem Gaussa, następnie 4-krotnie upsamplingu później. Zmniejsza to liczbę pikseli, które wymagają rozmycia przez 16X, a także zmniejsza rozmycie sigma z 48 na 12. iPhone 4S może rozmazać cały ekran w około 30 ms przy użyciu tego filtra.

Poprawne rozmywanie to jedno. Apple wciąż nie zapewnia szybkiego sposobu na umieszczenie zawartości obrazu poza swoimi widokami, dlatego najprawdopodobniej będzie to wąskie gardło dla szybko zmieniającej się zawartości.

+1

Tak więc przełączyłem się na "GPUImageiOSBlurFilter", co spowodowało znacznie szybsze renderowanie. Nie używam go do zamazywania na żywo, ale potrzebuję go do rozmycia obrazów wyświetlanych w "UITableViewCell's, więc musi szybko się cieszyć i robi to. Dzięki! – runmad

+0

Brad, czy mógłbyś zaktualizować specyfikacje pod GPU? Stara specyfikacja 0.1.1 nie zawiera "GPUImageiOSBlurFilter". Dzięki! –

+0

@KyrDunenkoff - Zakładam, że odnosisz się do CocoaPods? Nie utrzymuję niczego, ani nawet nie używam CocoaPods, więc to od tego, kto jest odpowiedzialny, wskażę najnowszą kompilację w repozytorium. Utrzymuję tylko repozytorium GitHub. Jeśli chcesz najnowszy kod, polecam ciągnięcie bezpośrednio z GitHub. –