transparence / alpha dans CoreGraphics contexte (iphone, objc)
-
26-09-2019 - |
Question
Je fais actuellement un éditeur d'image de base pour l'iphone.
Je prends la CGImageRef
d'un UIImage
et de créer un contexte à l'aide du code ci-dessous
origImage = result.CGImage;
Iheight = CGImageGetHeight(origImage);
Iwidth = CGImageGetWidth(origImage);
IcolorSpace = CGColorSpaceCreateDeviceRGB();
IrawData = malloc(Iheight * Iwidth * 4);
IbytesPerPixel = 4;
IbytesPerRow = IbytesPerPixel * Iwidth;
IbitsPerComponent = 8;
Icontext = CGBitmapContextCreate(IrawData, Iwidth, Iheight, IbitsPerComponent,
IbytesPerRow, IcolorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
);
//[bytesPerRow release];
CGContextSetBlendMode(Icontext, kCGBlendModeCopy);
CGContextDrawImage(Icontext, CGRectMake(0,0,Iwidth,Iheight), origImage);
I boucle ensuite à travers les pixels
for (int x=0; x<Iwidth; x++) {
for (int y=0; y<Iheight; y++) {
//and set the alpha component to 0
int byteIndex = (y*IbytesPerRow) + x*IbytesPerPixel;
IrawData[byteIndex+3] = 0;
}
}
et puis créez un CGImageRef du contexte avec
CGImageRef imagea = CGBitmapContextCreateImage(Icontext);
et ajoutez le CGImage à un UIImage et lui attribuer un UIImageView
Le problème est que le changement de alpha ne soit pas effectuer l'image résultante
si je change la couleur des pixels avec
IrawData[byteIndex+(0/1/2)]
les changements de couleur, mais Je ne peux toujours pas changer l'alpha du pixel
Merci,
nonono
La solution
Ne pas oublier de unpremultiply les couleurs avant de changer l'alpha, et re-Prémultiplier les ensuite.
couleur Prémultiplié (souvent appelé « prémultipliée alpha », ce qui est trompeur) signifie que les composants de couleurs sont stockés déjà multipliées par le alpha, afin de faciliter la composition. L'apparence de fonctionnement habituel compositing (source-over) comme ceci:
result = (source.rgb * source.a) + (destination.rgb * (1.0 - destination.a));
signifie prémultiplication que la première multiplication est déjà fait, il peut donc être ignoré:
result = source.rgb + (destination.rgb * (1.0 - destination.a));
Lorsque vous modifiez l'alpha sans changer les composants de couleur prémultipliées, le résultat ne change pas quand-vous dessinez l'image, il regardera pas différent, parce que les couleurs sont encore prémultipliées par l'ancien alpha.
Alors, vous devez unpremultiply les couleurs qui est, diviser chacun par l'alpha (comme précédemment, il a été multiplié, vous devez maintenant faire l'inverse) -Avant changer l'alpha. Puis, après avoir changé l'alpha, Prémultiplier les couleurs par la nouvelle alpha.
Bien sûr, cela signifie que lors du changement de l'alpha à zéro, toutes les couleurs devient noir (r = g = b = 0). Donc, assurez-vous de garder l'image originale si l'utilisateur pourrait vouloir changer de nouveau.
Il serait probablement plus efficace, et serait certainement plus facile à tirer juste l'image d'origine (sans alpha Les modifications apportées à elle) quel que soit l'alpha que l'utilisateur souhaite. Vous pouvez le faire par l'évolution globale alpha votre contexte d'affichage avant de dessiner l'image.