- 使用三元光栅操作实现透明贴图
基本概念
“三元光栅操作”是指源图像与目标图像的位合并操作。
操作对象涉及三个:源图像、目标图像、当前填充颜色(注:透明贴图不使用“当前填充颜色”)。
位操作包括:AND、NOT、OR、XOR。
全部的三元光栅操作码请参考 EasyX 在线帮助:https://docs.easyx.cn/ternary-raster-operations
例如,三元光栅操作码“PATPAINT”,查表得对应的布尔功能为“DPSnoo”(逆波兰表示法,其中 D、S、P 分别表示目标图像、源图像、当前填充颜色),该表达式展开后为:D or (P or (not S)),表示先将源图像按位取反,再与当前填充颜色执行 OR 操作,在与目标图像执行 OR 操作。这就是 putimage 函数以 PATPAINT 参数执行后的显示结果。
原图:需要透明的部分,用纯黑色表示。
掩码图:与原图对应。原图需要透明的部分,用纯黑色表示;原图需要显示的部分,用纯白色表示。
目标图:通常就是屏幕,不用担心屏幕显示什么。
注意:准备的图片与后面的代码是配套的。例如,原图 src3.gif 和掩码图 mask3.gif 处理成这样:
原图:

讯享网
掩码图:

然后用以下代码实现贴图:
#include <graphics.h> // EasyX_(beta) #include <conio.h> // 透明贴图函数 // 参数: // x, y: 目标贴图位置 // srcimg: 源 IMAGE 对象指针。NULL 表示默认窗体 // maskimg:掩码 IMAGE void transparentimage(int x, int y, IMAGE *srcimg, IMAGE *maskimg) {
putimage(x, y, maskimg, SRCAND); putimage(x, y, srcimg, SRCPAINT); } // 主函数 int main() {
initgraph(600, 400); // 初始化图形窗口 IMAGE src, mask; loadimage(&src, _T("D:\\src3.gif")); loadimage(&mask, _T("D:\\mask3.gif")); // 画个简单背景 setlinecolor(GREEN); for (int y = 0; y < 480; y += 3) line(0, y, 639, y); // 普通贴图 putimage(0, 0, &src); // 透明贴图 transparentimage(120, 0, &src, &mask); // 按任意键退出 _getch(); closegraph(); return 0; }
讯享网
以上代码的执行效果如下:

讯享网源 图:00 00 00 56 78 9a bc 00 (00 表示透明的部分(对应源图黑色部分(这个说法其实也不大对,因为羊的脚啊,嘴啊也是黑色的,但我们不需要其透明, 说到底还是该说成“要透明的部分”),其它数字表示显示的部分(对应源图需要显示的部分)) 掩码图:ff ff ff 00 00 00 00 ff (ff 表示透明的部分(对应掩码图白色部分),00 表示显示的部分(对应于掩码图黑色部分) 目标图:12 34 12 34 12 34 12 34
执行步骤:
初始目标图:12 34 12 34 12 34 12 34 执行:putimage(x, y, 掩码图, SRCAND); /* SRCAND 表示“掩码图(对于函数putimage来说掩码图就是源图像) AND 目标图(对于函数putimage来说掩码图就是目标图像,也就是画布)*/ 目标图变为:12 34 12 00 00 00 00 34 /*到这里简而言之就是发生了这样一件事:目标图像(画布)与掩码图(源图像)相与 而“与”运算是0&1=0,0&0=0,1&1=1,方便理解可以认为两个十六进制位的00就代表黑色(但这个说法超不严谨,懂的人麻烦评论区解释一下), 结果便是,掩码图的黑色部分覆盖了目标图像(画布),而由于FF等于全是1,与的结果便是维持目标图像原样, 于是目标图像 = 目标图像 AND 源图像, 即目标图像中只有掩码图黑色部分覆盖了目标图像*/ 执行:putimage(x, y, 源图, SRCPAINT); // SRCPAINT 表示“源图(源图像) OR 目标图(对于函数putimage来说掩码图就是目标图像,也就是画布)” /*这里由于上一步掩码图把要显示的区域覆盖成了黑色即全是0, 那么通过或运算,源图要显示的部分就会覆盖目标图像, 而不需要显示的部分由于是黑色,即FF等于全是1,或运算的特性导致其不会影响目标图像 于是便实现了源图只覆盖了目标图像中上一次操作后掩码图用黑色覆盖了的部分*/ 目标图变为:12 34 12 56 78 9a bc 34
根据以上原理可知:通过三元光栅操作实现透明贴图的办法有很多种,可以根据自己的源图、掩码图的状态写对应的代码。在前面的例子中,源图的透明部分是纯黑色,掩码图用纯白色表示透明的部分、纯黑色表示显示的部分。
这里再举一个不同的例子,在这个例子中,源图的透明部分用的是纯白色,掩码图用纯黑色表示透明的部分、纯白色表示显示的部分,如下:
讯享网源 图:ff ff ff 56 78 9a bc ff (ff 表示透明的部分,其它数字表示显示的部分) 掩码图:00 00 00 ff ff ff ff 00 (00 表示透明的部分,ff 表示显示的部分) 目标图:12 34 12 34 12 34 12 34
对应的执行步骤为:
初始目标图:12 34 12 34 12 34 12 34 执行:putimage(x, y, 掩码图, NOTSRCERASE); // NOTSRCERASE 表示“NOT(掩码图 OR 目标图)” 目标图变为:ed cb ed 00 00 00 00 cb 执行:putimage(x, y, 源图, SRCINVERT); // SRCINVERT 表示“源图 XOR 目标图” 目标图变为:12 34 12 56 78 9a bc 34
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/33829.html