Nur in der Theorie: Wie wird die Alpha-Komponente in die anderen Komponenten eines PNG in iPhone OS Premultiplied, und wie kann es richtig unpremultiplied werden?

StackOverflow https://stackoverflow.com/questions/870690

Frage

Eigentlich dachte ich, dass es eine einfache Möglichkeit, das zu erreichen. Was ich brauche, ist reine Alpha-Wert Informationen. Zum Testen habe ich ein 50 x 55 Pixel PNG, wo auf jeder Kante ein 5x5 Pixel-Rechteck vollständig transparent ist. In diesen Bereichen hat alpha 0.Everywhere anders sein, es 255. Ich hatte sehr sicher sein, dass mein PNG korrekt erstellt wird, und es sieht auch richtig.

Bitte sagen Sie mir, wenn dies theoretisch richtig ist: Ich habe ein CGImageRef, die nur den Alphakanal und nichts anderes hat. Dies wird mit CGBitmapContextCreate und kCGImageAlphaOnly als param getan. CGBitmapContextGetBitsPerPixel (Kontext) gibt mir 1, so dass es zeigt mir, dass ich nur eine Komponente pro Pixel wirklich: Der gewünschte Alpha-Wert. Ich habe gelesen, dass CGBitmapContextCreate alle die Umwandlung aus dem gegebenen Bild auf den neu geschaffenen Kontext behandelt. Mein Bild wurde zuvor PNG-24 mit Transparenz, aber pngcrunch von Xcode scheint sie irgendwie zu konvertieren.

Also, nur in der Theorie: Habe ich eine Chance habe auf den richtigen, unpremultiplied alpha an dieser Stelle zu bekommen? Die Werte, die ich bekomme scheinen fast Spiel, aber in einem großen 5x5 transparenten Quadrat I-Wert erhalten wie 19, 197, 210, 0, 0, 0, 98 und so weiter. Wenn sie wahr wären, würde ich etwas aus dem Bild zu sehen ist. Das Bild selbst ist durchgehend blau.

War es hilfreich?

Lösung

Vormultiplikation nicht den Alpha-Kanal beeinflussen, ist es die Farbkanäle beeinflusst.

Die Formel für Raster Compositing (Putting ein Rasterbild auf einem anderen) ist:

dst.r = src.r * src.a + dst.r * (1.0 - src.a);
dst.g = src.g * src.a + dst.g * (1.0 - src.a);
dst.b = src.b * src.a + dst.b * (1.0 - src.a);

Vormultiplikation schneidet den ersten Multiplikation Ausdruck:

dst.r = src.r′ + dst.r * (1.0 - src.a);
dst.g = src.g′ + dst.g * (1.0 - src.a);
dst.b = src.b′ + dst.b * (1.0 - src.a);

Das funktioniert, weil die Quellfarbkomponenten bereits durch die Alpha-Komponente-daher der Name multipliziert werden „Premultiplied“. Es braucht nicht, sie jetzt zu multiplizieren, weil es bereits die Ergebnisse hat.

  

unpremultiplied alpha

Die Alpha-Komponente selbst nie Premultiplied ist: Was würden Sie multiplizieren sie mit? Der Farbe Komponenten Premultiplied durch die alpha .

Andere Tipps

Da premultiplying Farbwerte ist ein einfaches Beispiel:

r = (r * a) / 255;
g = (g * a) / 255;
b = (b * a) / 255;

die inverse Erste wäre:

if (a > 0) {
    r = (r * 255) / a;
    g = (g * 255) / a;
    b = (b * 255) / a;
}

Dieses Formular ist nicht korrekt. Das Ziel ist unmultiplexed (r, g, b) das würde letztere Ergebnis die gleichen Multiplex-Werte (es ist nicht möglich, findet die Original-r, g, b-Werte, wenn auch zu finden.

Jedoch mit dem formular oben wir für das Beispiel von

finden
alpha = 100
r_premulti = 1

ein rekonstruiertes r = 2;

Latter wenn diese r wieder gemultiplext finden wir 2 * 100/255 = 0, aber wir wollten r_premulti == 1 statt !!

Das richtige Formular muss auf aufrunden . Beispiel für r-Komponente:

reconstruced r = ceiling(r_premulti * 255 / alpha)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top