使用SetWorkingImage后AlphaBlend函数贴图失效

0

在使用了SetWorkingImage之后再使用AlphaBlend函数就失效了

EasyX版本 : 20210730

Visual Studio版本 : 2019

做过的常识:

  1. 提前保存窗口HDC, 不奏效

下面是问题源码 (问题源码已经简化, 请不要讨论意义,必须使用AlphaBlend函数贴图, 具体项目保密)

#include <graphics.h>
#include <conio.h>

#pragma comment(lib, "MSIMG32.LIB")

void QPutimage(int x, int y, IMAGE* image, 
			int transparency = 255, IMAGE* target = NULL)
{
	HDC target_dc = GetImageHDC(target);
	HDC image_dc  = GetImageHDC(image);

	int width  = image->getwidth();
	int height = image->getheight();

	BLENDFUNCTION blend_function = { AC_SRC_OVER, 0, static_cast<BYTE>(transparency), AC_SRC_ALPHA };
	AlphaBlend(target_dc, x, y, width, height, 
				image_dc, 0, 0, width, height, 
				blend_function);
}

int main()
{
	initgraph(640, 480);

	IMAGE text_image(120, 120);
	
	SetWorkingImage(&text_image);
	outtextxy(0, 0, L"Hello World");
	SetWorkingImage(NULL);
	
	QPutimage(0, 0, &text_image);

	_getch();

    return 0;
}
ava
Margoo

2021-8-17

1

AlphaBlend 函数是依据颜色中的 Alpha 信息来决定透明度,0 表示完全透明,255 表示不透明。

而你准备的 text_image 虽然有文字输出,但是却没有修改 Alpha 通道的值,导致整个 text_image 都是透明的,因此贴图后什么都不显示。

你需要做的是通过直接操作显示缓冲区修改图片的透明度。注意,你需要同时调整 r、g、b 的值。你的代码修改后如下:

#include <graphics.h>
#include <conio.h>

#pragma comment(lib, "MSIMG32.LIB")

void QPutimage(int x, int y, IMAGE* image,
	int transparency = 255, IMAGE* target = NULL)
{
	HDC target_dc = GetImageHDC(target);
	HDC image_dc = GetImageHDC(image);

	int width = image->getwidth();
	int height = image->getheight();

	BLENDFUNCTION blend_function = { AC_SRC_OVER, 0, static_cast<BYTE>(transparency), AC_SRC_ALPHA };
	AlphaBlend(target_dc, x, y, width, height,
		image_dc, 0, 0, width, height,
		blend_function);
}

int main()
{
	initgraph(640, 480);

	IMAGE text_image(120, 120);

	SetWorkingImage(&text_image);
	outtextxy(0, 0, L"Hello World");
	setfillcolor(LIGHTMAGENTA);
	solidcircle(60, 60, 50);
	SetWorkingImage(NULL);

	// 增加 Alpha 信息,并根据 Alpha 调整颜色值
	BYTE a, r, g, b;
	DWORD* p = GetImageBuffer(&text_image);
	for (int i = 120 * 120 - 1; i >= 0; i--)
	{
		a = 255 * (i % 120) / 120;		// 水平渐变透明
		r = GetRValue(p[i]) * a / 255;
		g = GetGValue(p[i]) * a / 255;
		b = GetBValue(p[i]) * a / 255;
		p[i] = a << 24 | RGB(r, g, b);	// 实际内存中是 BGR 结构,前面分解颜色反着来,这里也反着来就好了
	}

	// 画个简单背景,以凸显透明效果
	setlinecolor(GREEN);
	for (int y = 0; y < 480; y += 3)
		line(0, y, 639, y);

	QPutimage(0, 0, &text_image);

	_getch();

	return 0;
}
ava
慢羊羊

2021-8-17

技术讨论社区