Bạn có thể giải thích cho tôi sự khác biệt giữa kCGImageAlphaPremultipliedFirst
và kCGImageAlphaFirst
không? Có nghĩa là gì Premultiplied
trong thực tế?kCGImageAlphaPremultipliedĐầu tiên và kCGImageAlphaFirst
Trả lời
Trong ngắn hạn, thủ tục có nghĩa là giá trị alpha cũng sẽ ảnh hưởng đến giá trị thành phần màu của pixel khi pixel không bị mờ.
Từ hướng dẫn vẽ Quartz 2D:
Đối với bitmap có một thành phần alpha, cho dù các thành phần màu đã nhân với giá trị alpha. Alpha số được mô tả trước tiên mô tả màu nguồn có thành phần đã được nhân với giá trị alpha . Premultiplying tăng tốc độ render một hình ảnh bằng cách loại bỏ một phép nhân bổ sung cho mỗi thành phần màu. Đối với ví dụ , trong không gian màu RGB, hiển thị hình ảnh với tiền tố alpha loại trừ ba phép toán nhân (lần đỏ alpha, lần màu xanh lá cây alpha và thời gian xanh alpha) cho mỗi pixel trong hình ảnh.
BTW, Pre-Multiplied có khả năng là các API sẽ buộc bạn sử dụng vì đó là tùy chọn của Quartz. May mắn thay, các chuyển đổi không phải là khủng khiếp (OTOH mất ...).
cách ngắn nhất để giải thích điều này là ở float
thành phần, sử dụng dải [0...1]
.
Nếu đại diện RGBA đầu vào của chúng tôi là:
typedef struct t_rgba { float r,g,b,a; } t_rgba;
const t_rgba rgba = { 0.5, 0.5, 0.5, 0.5 };
Sau đó, để trước nhân nó:
t_rgba rgba_PreMul = rgba;
rgba_PreMul.r *= rgba_PreMul.a;
rgba_PreMul.g *= rgba_PreMul.a;
rgba_PreMul.b *= rgba_PreMul.a;
Sau đó, để de-pre-nhân nó:
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;
}
Bạn có thể cũng muốn một chút bão hòa ở đó.
Bây giờ, đó là biểu mẫu cơ bản, có thể được đặt lại cho các biểu diễn dạng số khác. Lưu ý rằng các chuyển đổi này bị mất mát. Đồng thời, hãy cẩn thận không vượt qua các bitmap sơ bộ, nơi các bitmap thông thường được mong đợi và ngược lại.
Tôi có pixel [(255/255.0), (100/255.0), (20/255.0), (40/255.0)]. Nếu tôi hiểu chính xác 'premultiplied' có nghĩa là' red * = (40/255.0) 'và như vậy, nhưng khi tôi sử dụng' kCGImageAlphaFirst' thì 'red = red'? –
@TomaszSzulc yes. và mở rộng. – justin
Cảm ơn bạn rất nhiều. –