【发布时间】:2014-11-16 11:21:04
【问题描述】:
我正在尝试创建一种算法,以在完全不透明的图像之上覆盖具有透明度的图像。 在下一个示例中,我有一个完全不透明的背面图像,以及一个带有漫射边缘的蓝色框架的正面图像。 我遇到的问题是我的实现错误地覆盖了产生暗像素的半透明区域。
这是我的实现:
#define OPAQUE 0xFF
#define TRANSPARENT 0
#define ALPHA(argb) (uint8_t)(argb >> 24)
#define RED(argb) (uint8_t)(argb >> 16)
#define GREEN(argb) (uint8_t)(argb >> 8)
#define BLUE(argb) (uint8_t)(argb)
#define ARGB(a, r, g, b) (a << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)
#define BLEND(a, b, alpha) ((a * alpha) + (b * (255 - alpha))) / 255
void ImageUtil::overlay(const uint32_t* front, uint32_t* back, const unsigned int width, const unsigned int height)
{
const size_t totalPixels = width * height;
for (unsigned long index = 0; index < totalPixels; index++)
{
const uint32_t alpha = ALPHA(*front);
const uint32_t R = BLEND(RED(*front), RED(*back), alpha);
const uint32_t G = BLEND(GREEN(*front), GREEN(*back), alpha);
const uint32_t B = BLEND(BLUE(*front), BLUE(*back), alpha);
*backPixels++ = ARGB(OPAQUE, R , G, B);
*frontPixels++;
}
}
更新:
测试图像文件
【问题讨论】:
-
调试时发现了什么?
-
您是如何加载图像的?您的图像加载器是否可以预乘该图像?
-
图片加载正确。我已经尝试过分别加载和保存它们而不合并,这会产生相同的原始图像。我认为问题可能出在混合像素的公式中,但我无法发现问题。
-
标准的 alphablend 算法是
((RGB1 * alpha) + (RGB2 * (255 - alpha))) / 255。 -
也许你的正面图像有预乘 alpha。如果确实如此,并且您再次将其乘以 alpha,它将导致您得到的结果(alpha 不是 0 或 255 的较暗结果)。
标签: c++ overlay alpha pixels blend