Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sf::Image::copy() - Fixed the incorrect alpha value being calculated for semi-transparent pixels on fully transparent pixels #1993

Merged
merged 1 commit into from Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions include/SFML/Graphics/Image.hpp
Expand Up @@ -203,9 +203,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
Expand Down
19 changes: 13 additions & 6 deletions src/SFML/Graphics/Image.cpp
Expand Up @@ -240,12 +240,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<Uint8>((src[0] * alpha + dst[0] * (255 - alpha)) / 255);
dst[1] = static_cast<Uint8>((src[1] * alpha + dst[1] * (255 - alpha)) / 255);
dst[2] = static_cast<Uint8>((src[2] * alpha + dst[2] * (255 - alpha)) / 255);
dst[3] = static_cast<Uint8>(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<Uint8>(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<Uint8>((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;
Expand Down