Juste en théorie: Comment est la composante alpha prémultipliée dans les autres composants d'un PNG dans iPhone OS, et comment peut-il être unpremultiplied correctement?

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

Question

En fait, je pensais qu'il y aurait un moyen facile d'y parvenir. Ce que je dois l'information pure valeur alpha. Pour les tests, j'ai 50 x 55 px PNG, où sur chaque bord d'un rectangle de pixels 5x5 est totalement transparent. Dans ces zones alpha doit être 0.Everywhere sinon il doit être 255. Je fait bien sûr que mon PNG est créé correctement, et il semble aussi correctement.

S'il vous plaît me dire si cela est théoriquement correcte: J'ai créé un CGImageRef qui a seul le canal alpha et rien d'autre. Cela se fait avec CGBitmapContextCreate et kCGImageAlphaOnly comme param. CGBitmapContextGetBitsPerPixel (contexte) me me retourne 1, il indique que j'ai vraiment qu'un seul élément par pixel: La valeur alpha désirée. J'ai lu que CGBitmapContextCreate va gérer toute la conversion de l'image donnée au nouveau contexte créé. Mon image a été PNG-24 précédemment avec la transparence, mais pngcrunch de Xcode semble les convertir en quelque sorte.

Alors, juste en théorie: Ai-je une chance de se rendre à l'alpha correcte, unpremultiplied à ce point? Les valeurs que je reçois semblent presque correspondance, mais dans un grand 5x5 transparent je reçois des valeurs telles que 19, 197, 210, 0, 0, 0, 98 et ainsi de suite. Si elles étaient vraies, je dois voir quelque chose de l'image. L'image elle-même est bleu.

Était-ce utile?

La solution

prémultiplication ne modifie pas le canal alpha, il agit sur les canaux de couleur.

La formule de la composition de trame (mettre une image de trame sur l'autre) est la suivante:

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);

coupes de prémultiplication sur la première expression de multiplication:

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);

Cela fonctionne parce que les composants de couleur source sont déjà multipliées par l'alpha-composant d'où le nom « prémultipliées ». Il n'a pas besoin de les multiplier maintenant, car il a déjà les résultats.

  

unpremultiplied alpha

Le composant alpha est lui-même ne prémultipliées: Que feriez-vous multiplier par? Le couleur composants sont prémultipliées par l'alpha .

Autres conseils

Étant donné que les valeurs de couleur prémultiplication est simple:

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

Obtenir l'inverse serait:

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

Ce formulaire n'est pas correct. L'objectif est de trouver unmultiplexed (r, g, b) qui serait dernier résultat aux mêmes valeurs multiplexées (il est impossible de trouver le r original, g, b des valeurs, cependant.

Cependant, avec l'formular ci-dessus, nous trouvons l'exemple de

alpha = 100
r_premulti = 1

a r reconstruit = 2;

Derniers si ce r est multiplexée à nouveau, nous trouvons 2 * 100/255 = 0 mais nous voulions r_premulti == 1 à la place !!

Le formular correct a besoin de arrondir . Exemple de composant r:

reconstruced r = ceiling(r_premulti * 255 / alpha)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top