使用半透明算法加载一个缓冲区画点,再组成其他的几何图形,以下代码里,矩形半透明没有任何问题,但是一个星星形状的图形,进行半透明运算反去过的效果有黑线,然后就是一个绘图缓冲区益出问题,不知是什么问题,如果有人解决可以有偿。微信:NYJ13620
下面是一个修复半透明红色和红色变黑的源代码:
#include<stdio.h>
#include<graphics.h>
DWORD* g_pBuf;
// 进行前景色和背景色半透明计算。
COLORREF Alphargb(int r1, int g1, int b1, int r2, int g2, int b2, int alp)
{ COLORREF rgb1 =RGB((((r1 - alp) * r1) + (alp * r2)) * 0.01,(((g1 - alp) * g1) + (alp * g2)) * 0.01,(((b1 - alp) * b1) + (alp * b2)) * 0.01);
return rgb1;
}
// 显示缓冲区指针
COLORREF fast_getpixel(int x, int y, int WIDTH){COLORREF c = g_pBuf[y * WIDTH + x];return BGR(c);}
// 快速画点函数
void fast_putpixel(int x, int y, int WIDTH, COLORREF c)
{
COLORREF bj;
bj = fast_getpixel(x, y, WIDTH);
int r2 = GetRValue(c),g2 = GetGValue(c),b2 = GetBValue(c),r1 = GetRValue(bj),g1 = GetGValue(bj),b1 = GetBValue(bj);
COLORREF bjys = getbkcolor();
COLORREF bj1 = BGR(r1, g1, b1);
if (bjys == bj){ g_pBuf[abs(y * WIDTH + x)] = BGR(c);}
if (bjys != bj){g_pBuf[abs(y * WIDTH + x)] = BGR(Alphargb(r2, g2, b2, r1, g1, b1, 60));}
}
void rec(int x1, int y1, int x2, int y2, COLORREF c)
{ int WIDTH = getwidth();
for (int i = y1; i < y1 + (y2 - y1); i++){for (int j = x1; j < x1 + (x2 - x1); j++){ fast_putpixel(j, i, WIDTH, c);}}
}
int main()
{
initgraph(800, 800);
g_pBuf = GetImageBuffer();
int rz = 100, gz = 0, bz = 0, a = 1;
ExMessage m; // 定义消息变量
BeginBatchDraw();
while (true)
{ // 获取一条鼠标或按键消息
m = getmessage(EX_MOUSE | EX_KEY);
switch (m.message)
{
case WM_MOUSEMOVE:
// 鼠标移动的时候画红色的小点
rec(100, 100, 200, 200, RED);
rec(150, 150, 150 + 100, 150 + 100, GREEN);
rec(200, 200, 200 + 100, 200 + 100, BLUE);
rec(200 + 50, 200 + 50, 250 + 100, 250 + 100, WHITE);
rec(300, 300, 300 + 100, 300 + 100, LIGHTMAGENTA);
rec(250 + 100, 250 + 100, 350 + 100, 350 + 100, YELLOW);
rec(m.x, m.y, m.x + 100, m.y + 100, RGB(rz, gz, bz));
FlushBatchDraw();
break;
case WM_LBUTTONDOWN:
a = rand() % 3 + 1;
if (a == 1) { rz = 100; gz = 0; bz = 0; }if (a == 2) { rz = 0; gz = 100; bz = 0; }if (a == 3) { rz = 0; gz = 0; bz = 100; }
break;
}
cleardevice();
}
EndBatchDraw();
getmessage(EX_CHAR);
closegraph();
return 0;
}
问题代码:
// EasyX 简单缓冲区半透明画点,让你的绘图支持任意的透明度,达到让大家推波推润的效果。
// 2023 - 4 - 7
// 作者:舞乐葉
// QQ:2250395955
#define WINVER 0x0A00
#define _WIN32_WINNT 0x0A00
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
#include <math.h>
#include <ShellScalingApi.h> // 引用头文件
#pragma comment(lib, "Shcore.lib") // 链接库文件
// 打开缓冲区。
DWORD* g_pBuf;
// 进行前景色和背景色半透明计算。
COLORREF Alphargb(int r1, int g1, int b1, int r2, int g2, int b2, int alp)
{ COLORREF rgb1 = RGB((((r1 - alp) * r1) + (alp * r2)) * 0.01, (((g1 - alp) * g1) + (alp * g2)) * 0.01, (((b1 - alp) * b1) + (alp * b2)) * 0.01);
return rgb1;
}
// 显示缓冲区指针,并读取坐标上的颜色值。
COLORREF fast_getpixel(int x, int y, int WIDTH) { COLORREF c = g_pBuf[y * WIDTH + x]; return BGR(c); }
// 快速缓冲区半透明画点函数 2
void putpixel1(DWORD* g_pBuf, int x, int y, COLORREF c)
{ int xxx = getwidth(), ax = (y * xxx + x), WIDTH = getwidth(), puti = abs(y * WIDTH + x);
if (puti <= 1){puti == 5;}
if (puti <= (getwidth() * getheight())){puti - 5;}
COLORREF bj, bjys = getbkcolor();
// 读取背景上的颜色点。
bj = fast_getpixel(x, y, xxx);
//if (bj != WHITE) bj = fast_getpixel(x, y, xxx);
// 声明定义背景颜色和绘图的颜色。
int r2 = GetRValue(c), g2 = GetGValue(c), b2 = GetBValue(c), r1 = GetRValue(bj), g1 = GetGValue(bj), b1 = GetBValue(bj);
// 获取背景颜色和绘图颜色,并进行透明混合计算和,排除不是透明的部分。
COLORREF bj1 = BGR(r1, g1, b1);
// 排除非透明区域的颜色,只混合有颜色的区域。
if (bjys == bj) { g_pBuf[puti] = BGR(c); }
if (bj != bjys) { g_pBuf[puti] = BGR(Alphargb(r2, g2, b2, r1, g1, b1, 60)); }
}
// 画支持透明的矩形。
void rec(int x1, int y1, int x2, int y2, COLORREF c)
{// 获取绘图区宽度。
int WIDTH = getwidth(); g_pBuf = GetImageBuffer();
for (int i = y1; i < y1 + (y2 - y1); i++)for (int j = x1; j < x1 + (x2 - x1); j++)putpixel1(g_pBuf, j, i, c);
}
// 中点画圆法,转为星星形状
void Circle_Midpoint5(int x, int y, int r, int color, int temp)
{ DWORD* pu = GetImageBuffer();
int tx = 0, ty = r, d = 1 - r, d1 = 0;
while (tx <= ty)
{ if (temp == 1)
{ (x + tx, y + ty, color);
putpixel1(pu, x + ty, y + tx, color); d1 = 0;
for (int i = (x + tx); i <= (x + r); i++) { putpixel1(pu, (x + tx) + d1, y + ty, color); d1++; } d1 = 0;
for (int i = (x + ty); i <= (x + r); i++) { putpixel1(pu, (x + ty) + d1, y + tx, color); d1++; }
}
if (temp == 2)
{ putpixel1(pu, x - ty, y + tx, color); putpixel1(pu, x - tx, y + ty, color); d1 = 0;
for (int i = (x - ty); i >= (x - r); i--) { putpixel1(pu, (x - ty) + d1, y + tx, color); d1--; } d1 = 0;
for (int i = (x - tx); i >= (x - r); i--) { putpixel1(pu, (x - tx) + d1, y + ty, color); d1--; }
}
if (temp == 3)
{ putpixel1(pu, x - ty, y - tx, color); putpixel1(pu, x - tx, y - ty, color); d1 = 0;
for (int i = (x - ty); i >= (x - r); i--) { putpixel1(pu, (x - ty) + d1, y - tx, color); d1--; } d1 = 0;
for (int i = (x - tx); i >= (x - r); i--) { putpixel1(pu, (x - tx) + d1, y - ty, color); d1--; }
}
if (temp == 4)
{ putpixel1(pu, x + tx, y - ty, color); putpixel1(pu, x + ty, y - tx, color); d1 = 0;
for (int i = (x + tx); i <= (x + r); i++) { putpixel1(pu, (x + tx) + d1, y - ty, color); d1++; } d1 = 0;
for (int i = (x + ty); i <= (x + r); i++) { putpixel1(pu, (x + ty) + d1, y - tx, color); d1++; }
}
if (d < 0)d += 2 * tx + 3; else d += 2 * (tx - ty) + 5, ty--;
tx++;
}
}
void star(int x, int y, int lie = NULL)
{ int x1 = x - lie, y1 = y - lie; int x2 = x + lie, y2 = y - lie; int x3 = x + lie, y3 = y + lie; int x4 = x - lie, y4 = y + lie;
Circle_Midpoint5(x1, y1, lie, RED, 1); Circle_Midpoint5(x2, y2, lie, RED, 2);
Circle_Midpoint5(x3, y3, lie, RED, 3); Circle_Midpoint5(x4, y4, lie, RED, 4);
}
// 主函数
int main()
{ SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
// 创建绘图窗口
initgraph(800, 800);
g_pBuf = GetImageBuffer();
BeginBatchDraw(); // 开启批量绘图
ExMessage m;
while (true)
{ // 获取一条鼠标或按键消息
peekmessage(&m, EX_MOUSE | EX_KEY, true);
rec(100, 100, 200, 200, RED);
rec(150, 150, 150 + 100, 150 + 100, GREEN);
rec(200, 200, 200 + 100, 200 + 100, BLUE);
rec(200 + 50, 200 + 50, 250 + 100, 250 + 100, WHITE);
rec(300, 300, 300 + 100, 300 + 100, LIGHTMAGENTA);
rec(250 + 100, 250 + 100, 350 + 100, 350 + 100, YELLOW);
switch (m.message)
{
case WM_MOUSEMOVE:star(m.x, m.y, 100);rec(m.x + 100, m.y, m.x + 200, m.y + 100, RED);
break;
}
FlushBatchDraw();
cleardevice();
}
_getch();
EndBatchDraw();
closegraph();
return 0;
}