From 9509b59beae1876326101282982879eda2aa4b00 Mon Sep 17 00:00:00 2001 From: Peter Chapman Date: Mon, 14 Feb 2022 10:43:08 +1300 Subject: [PATCH] Fixed incorrect value for fully transparent pixels --- include/SFML/Graphics/Image.hpp | 10 +++++++--- src/SFML/Graphics/Image.cpp | 19 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/include/SFML/Graphics/Image.hpp b/include/SFML/Graphics/Image.hpp index d58989135c..309058a1cb 100644 --- a/include/SFML/Graphics/Image.hpp +++ b/include/SFML/Graphics/Image.hpp @@ -228,9 +228,13 @@ class SFML_GRAPHICS_API Image /// kind of feature in real-time you'd better use sf::RenderTexture. /// /// If \a sourceRect is empty, the whole image is copied. - /// If \a applyAlpha is set to true, the transparency of - /// source pixels is applied. If it is false, the pixels are - /// copied unchanged with their alpha value. + /// If \a applyAlpha is set to true, alpha blending is + /// applied from the source pixels to the destination pixels + /// using the \b over operator. If it is false, the source + /// pixels are copied unchanged with their alpha value. + /// + /// See https://en.wikipedia.org/wiki/Alpha_compositing for + /// details on the \b over operator. /// /// \param source Source image to copy /// \param destX X coordinate of the destination position diff --git a/src/SFML/Graphics/Image.cpp b/src/SFML/Graphics/Image.cpp index 010023c5f3..d6dfe6b506 100644 --- a/src/SFML/Graphics/Image.cpp +++ b/src/SFML/Graphics/Image.cpp @@ -257,12 +257,19 @@ void Image::copy(const Image& source, unsigned int destX, unsigned int destY, co const Uint8* src = srcPixels + j * 4; Uint8* dst = dstPixels + j * 4; - // Interpolate RGBA components using the alpha value of the source pixel - Uint8 alpha = src[3]; - dst[0] = static_cast((src[0] * alpha + dst[0] * (255 - alpha)) / 255); - dst[1] = static_cast((src[1] * alpha + dst[1] * (255 - alpha)) / 255); - dst[2] = static_cast((src[2] * alpha + dst[2] * (255 - alpha)) / 255); - dst[3] = static_cast(alpha + dst[3] * (255 - alpha) / 255); + // Interpolate RGBA components using the alpha values of the destination and source pixels + Uint8 src_alpha = src[3]; + Uint8 dst_alpha = dst[3]; + Uint8 out_alpha = static_cast(src_alpha + dst_alpha - src_alpha * dst_alpha / 255); + + dst[3] = out_alpha; + + if (out_alpha) + for (int k = 0; k < 3; k++) + dst[k] = static_cast((src[k] * src_alpha + dst[k] * (out_alpha - src_alpha)) / out_alpha); + else + for (int k = 0; k < 3; k++) + dst[k] = src[k]; } srcPixels += srcStride;