let’s dev

Blog

Top!

let’s dev | Scroll to top
let’s dev | Scroll to next content item

Hello

let’s dev | Scroll to previous content item
let’s dev Blog | Blur-Effekte unter iOS 7
by Katja
24. April 2014

Blur-Effekte unter iOS 7

Mit der Einführung von iOS 7 kam durch den Einsatz von geblurrten Menus auch in der Entwicklergemeinde ein gesteigertes Interesse am Thema Blur auf.

Möchte man als Entwickler seine eigene App an das neue Look & Feel anpassen ist der Einsatz des Blur-Effekts unumgänglich. In einfachen statischen Szenarien kann das geblurrte Menu mit Hilfe der von Apple gelieferten Core Image Bibliothek und deren Filter implementiert werden [1].

Blur-Effekt vs. normale Darstellung

Abbildung 1: Blur-Effekt vs. normale Darstellung

Werden dynamische oder gar dreidimensionale Inhalte verwendet stößt man allerdings schnell an die Grenzen der Bibliothek. Muss der Blur zur Laufzeit berechnet werden, sorgt dies für unzumutbare Wartezeiten für den Benutzer.

Eine effizientere Möglichkeit zur Berechnung ist die Verwendung der Graphikhardware mittels OpenGL ES in dem von Apple zur Verfügung gestellten GLKViewController aus dem GLKit Framework [2]. Bevor wir hierauf näher eingehen, soll zunächst das Konzept des Blur-Effekts erläutert werden.

Der Blur-Effekt, besser bekannt als Weichzeichner, durchläuft alle Pixel eines Bildes und berechnet den neuen Farbwert unter Berücksichtigung der benachbarten Pixel. Dazu wird eine Filtermatrix verwendet die festlegt mit welcher Gewichtung benachbarte Pixel in den resultierenden Farbwert einfließen. Einer der bekanntesten Filter dieser Art ist wohl der Gaußfilter, dessen Matrix wie folgt definiert ist:

Mathematische Formel zur Berechnung des Gaußfilters

Abbildung 2: Mathematische Formel zur Berechnung des Gaußfilters

Detailliertere Informationen über die Funktionsweise und die mathematischen Hintergründe des Gaußfilters sind in den nachfolgenden Referenzen [3] oder [4] zu finden.

Abgesehen von der verwendeten Filterart spielt auch der Radius des Filters eine Rolle. Je höher die Anzahl der einbezogenen Pixel gewählt wird, desto stärker wird das Bild weichgezeichnet. Gleichzeitig steigt jedoch auch der Aufwand für die Berechnung erheblich an. Mit steigendem Filterradius nimmt die Anzahl der zu betrachtenden Pixel quadratisch zu.

Da Pixelzugriffe den größten Teil der Rechenzeit ausmachen und gerade im mobilen Bereich die Ressourcen sehr begrenzt sind, ist es empfehlenswert die Anzahl der Zugriffe so gering wie möglich zu halten. Durch die Separierbarkeit des Gauß-Filters ist es möglich, die Filterung auf ein 2D-Bild in zwei 1-dimensionale Filterungen aufzuteilen. Somit wird das Bild einmal vertikal und einmal horizontal gefiltert. Dies verringert die Anzahl der Zugriffe im Falle eines 9×9 Filters von 81 auf 18. Das folgende Bild verdeutlicht die Anwendung dieses Konzepts:

Blur horizontal

Abbildung 3: Blur horizontal

Blur vertikal

Abbildung 4: Blur vertikal

Blur Resultat

Abbildung 5: Ergebnis

Die Realisierung des beschriebenen Konzepts in OpenGL ES erfolgt über Pixel Berechnungen im Fragment Shader. Dazu wird der gewünschte Bildbereich zunächst mit Hilfe eines Framebuffer Objects in eine Textur gerendert. Auf diese Textur wird anschließend die Filteroperation im Shader angewandt.

Um das Konzept des separierten Filters anzuwenden ist es notwendig 2 Framebuffer zu verwenden. Aus dem einem Buffer wird das ungeblurte Bild gelesen und in den zweiten wird das resultierende Bild gespeichert. Nach dem Durchlauf des horizontalen Blurs werden die Buffer vertauscht und der vertikale Blur durchlaufen.

Eine mögliche Realisierung eines solchen Shaders nach Vorlage von [5] ist in dem nachfolgenden Code Snippet zu sehen.

uniform sampler2D image;
                uniform highp float blurSize;

                void main(void) {
                   highp float offset[3];
                   offset[0] = 0.0;
                   offset[1] = 1.3846153846;
                   offset[2] = 3.2307692308;
                   highp float weight[3];
                   weight[0] = 0.2270270270;
                   weight[1] = 0.3162162162;
                   weight[2] = 0.0702702703;

                   gl_FragColor = texture2D( image, vec2(gl_FragCoord) / blurSize) * weight[0];

                   for (int i=1; i<3; i++) {
                      gl_FragColor += texture2D( image, ( vec2(gl_FragCoord)+vec2(offset[i], 0.0) ) / blurSize) * weight[i];
                      gl_FragColor += texture2D( image, ( vec2(gl_FragCoord)-vec2(offset[i], 0.0) ) / blurSize) * weight[i];
                   }
                }
}       

Entspricht das resultierende Bild nicht der gewünschten Blur-Intensität, kann dieser Vorgang beliebig oft wiederholt werden. Anschließend steht das fertig Bild mit Blur-Effekt als Textur zur Verfügung und kann zur Zeichnung der GUI-Elemente verwendet werden. Erfahrungsgemäß sind je nach Größe des geblurrten Bildbereichs unter OpenGL ES 2.0 auf dem iPad 3 schon bis zu fünf Wiederholungen möglich.

Treten trotz der separierten Filter Performance-Probleme auf ist es möglich die Framebuffer in einer niedrigeren Auflösung zu speichern, da die Bilder nach Anwendung des Filters nur noch niederfrequente Bildanteile besitzen.

In einfachen Fällen ist es möglich die benötigten Texturen bereits geblurrt zu hinterlegen und zur Darstellung der GUI-Elemente zu verwenden. Um eine vorgeblurrte Textur zu erstellen, genügt es mit Hilfe aktueller Bildbearbeitungssoftware einen entsprechenden Filter über das Bild zu legen, und das Bild in gefiltertem Zustand abzuspeichern. Steht genügend Speicher zur Verfügung ist die Vorberechnung zu empfehlen.

Im konkreten Einzelfall muss die Wahl der Methode in Abhängigkeit bestimmter Faktoren – der Komplexität des Szenarios und der Verfügbarkeit der Rechenleistung und des Speichers – erfolgen. Eine abschließende allgemein gültige Empfehlung kann also nicht gegeben werden.

Bildnachweis Abbildung 3-5:

  • ATI Technologies Inc.

Weitere Artikel aus unserem Blog

let’s dev Blog | let's dev unterstützt SG Siemens Volleyballer aus Karlsruhe

Corporate

let's dev unterstützt SG Siemens Volleyballer aus Karlsruhe

by Helena

2018-12-04

Weiterlesen
let’s dev Blog | KMU gestalten die Digitalisierung – Mittelstandskonferenz 2018

Corporate

KMU gestalten die Digitalisierung – Mittelstandskonferenz 2018

by Helena

2018-11-12

Weiterlesen
let’s dev Blog | Apple Wallet

Technical

Apple Wallet

by Maik

2018-10-26

Weiterlesen
let’s dev Blog | „Mensch und Computer“ 2018

Corporate

„Mensch und Computer“ 2018

by Judith

2018-09-24

Weiterlesen
let’s dev Blog | State Design Pattern in Android

Technical

State Design Pattern in Android

by Thomas

2018-09-17

Weiterlesen
let’s dev Blog | let’s dev ist autorisiertes Beraterunternehmen im Förderprogramm „go-digital“

Corporate

let’s dev ist autorisiertes Beraterunternehmen im Förderprogramm „go-digital“

by Helena

2018-09-01

Weiterlesen
let’s dev Blog | App Design & Development Conference 2018

Corporate

App Design & Development Conference 2018

by Helena

2018-08-14

Weiterlesen
let’s dev Blog | iOS 12: Die Top-Neuerungen im Überblick

Technical

iOS 12: Die Top-Neuerungen im Überblick

by Nicolas

2018-07-17

Weiterlesen
let’s dev Blog | let’s dev auf der CEBIT

Corporate

let’s dev auf der CEBIT

by Karl

2018-06-11

Weiterlesen
let’s dev Blog | Einführung in User Interface (UI) Tests mit Espresso

Technical

Einführung in User Interface (UI) Tests mit Espresso

by Raphael

2018-06-07

Weiterlesen
let’s dev Blog | Die App im Apple App Store: welche Informationen werden benötigt?

Technical

Die App im Apple App Store: welche Informationen werden benötigt?

by Aileen

2018-04-27

Weiterlesen
let’s dev Blog | Smart Pointer in C++

Technical

Smart Pointer in C++

by Matthias

2018-04-01

Weiterlesen
let’s dev Blog | User Interface Design für das iPhone X: alle Neuerungen auf einen Blick

Technical

User Interface Design für das iPhone X: alle Neuerungen auf einen Blick

by Helena

2018-02-07

Weiterlesen
let’s dev Blog | WebVR – Virtual Reality Experience im Browser mit dem A-Frame Framework

Technical

WebVR – Virtual Reality Experience im Browser mit dem A-Frame Framework

by Judith

2018-01-10

Weiterlesen
let’s dev Blog | Open Data Hackathon der Deutschen Bahn

Corporate

Open Data Hackathon der Deutschen Bahn

by Karl

2015-03-31

Weiterlesen
let’s dev Blog | Beyond App Store – Distribution von iOS-Anwendungen

Technical

Beyond App Store – Distribution von iOS-Anwendungen

by Karl

2012-08-27

Weiterlesen
let’s dev Blog | Frontend-Architektur – Model View Presenter und Message Bus

Technical

Frontend-Architektur – Model View Presenter und Message Bus

by Karl

2011-03-08

Weiterlesen