objective c - kCGImageAlphaPremultipliedFirst y kCGImageAlphaFirst
objective-c bitmap (1)
En resumen, premultiplicado significa que el valor alfa también afectará a los valores del componente de color de los píxeles cuando se representa un píxel que no es opaco.
De la guía de dibujo en 2D de Quartz:
Para mapas de bits que tienen un componente alfa, si las componentes de color ya están multiplicadas por el valor alfa. Premultiplicado alfa describe un color de origen cuyas componentes ya están multiplicadas por un valor alfa. Premultiplying acelera la renderización de una imagen al eliminar una operación de multiplicación adicional por componente de color. Por ejemplo, en un espacio de color RGB, renderizar una imagen con alfa premultiplicado elimina tres operaciones de multiplicación (rojo por alfa, verde por alfa y azul por alfa) para cada píxel en la imagen.
Por cierto, pre-multiplicado es probable que lo que las API te obliguen a usar porque es la preferencia de Quartz. Afortunadamente, las conversiones no son terribles (pérdidas OTOH ...).
la forma más rápida de explicar esto es en componentes float
, usando el rango [0...1]
.
Si nuestra representación de entrada RGBA es:
typedef struct t_rgba { float r,g,b,a; } t_rgba;
const t_rgba rgba = { 0.5, 0.5, 0.5, 0.5 };
Entonces para pre-multiplicarlo:
t_rgba rgba_PreMul = rgba;
rgba_PreMul.r *= rgba_PreMul.a;
rgba_PreMul.g *= rgba_PreMul.a;
rgba_PreMul.b *= rgba_PreMul.a;
Entonces para de-pre-multiplicarlo:
t_rgba rgba_DePreMul = rgba_PreMul;
if (0.0 < rgba_DePreMul.a && 1.0 > rgba_DePreMul.a) {
const float ialpha = 1.0/rgba_DePreMul.a;
rgba_DePreMul.r *= ialpha;
rgba_DePreMul.g *= ialpha;
rgba_DePreMul.b *= ialpha;
}
Es posible que desee un poco de saturación allí también.
Ahora esa es la forma básica, que puede ser reutilizada para otras representaciones numéricas. Tenga en cuenta que estas conversiones son con pérdida . Además, tenga cuidado de no pasar bitmaps premultiplicados donde se esperan mapas de bits regulares, y viceversa.
¿Puede explicarme la diferencia entre kCGImageAlphaPremultipliedFirst
y kCGImageAlphaFirst
? ¿Qué significa Premultiplied
en la práctica?