#include <iostream>
#include <algorithm>
#include <cstdio>
#include <easyx.h>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <conio.h>
#include "resource.h"
using namespace std;
struct snow
{
int grey, r;
int x, y, dx, dy;
};
vector<int> cols; // 去重灰度表
int gry[5005][5005]; // 记录原图的真实灰度
vector<snow> lis; // 雪花表
int main()
{
srand(time(NULL));
IMAGE img;
loadimage(&img, _T("PNG"), MAKEINTRESOURCE(IDB_PNG1));
int n = img.getwidth(), m = img.getheight();
puts("正在预处理...");
SetWorkingImage(&img);
double lst = 0;
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= m; j++)
{
// 登记像素点灰度
COLORREF col = getpixel(i, j);
int R = GetRValue(col), G = GetGValue(col), B = GetBValue(col);
int grey = (R * 39190 + G * 76939 + B * 14943) >> 17;
gry[i][j] = grey;
cols.push_back(grey);
// 计算加载进度
double pre = ((i - 1) * (m + 1) + j + 1) / (double)((n + 1) * (m + 1));
if (pre - lst > 0.008)
{
lst = pre;
printf("进度: %.2lf%%\n", pre * 100);
}
}
}
// 去重
sort(cols.begin(), cols.end());
cols.erase(unique(cols.begin(), cols.end()), cols.end());
SetWorkingImage(NULL);
initgraph(n, m, EW_SHOWCONSOLE);
BeginBatchDraw();
IMAGE now;
Resize(&now, n, m);
while (1)
{
// 随机挑选原图像素点制造雪花
for (int i = 1; i <= 10 && lis.size() < 500; i++)
{
snow tmp;
tmp.grey = cols[rand() % cols.size()];
tmp.y = 0;
tmp.x = rand() % (int)(n * 1.5);
tmp.r = rand() % 3 + 1;
tmp.dx = -(rand() % 2 + 1);
tmp.dy = rand() % 2 + 1;
lis.push_back(tmp);
}
cleardevice();
putimage(0, 0, &now);
// 雪花纷飞
for (int i = 0; i < lis.size(); i++)
{
int tmp = lis[i].grey;
// 雪花飞到某点,若此点与原图灰度相仿,则将雪花改为该点颜色
if (abs(lis[i].grey - gry[lis[i].x][lis[i].y]) <= 50)
{
lis[i].grey = gry[lis[i].x][lis[i].y];
}
bool f = true;
// 在雪花圆圈内遍历点
for (int x = lis[i].x - lis[i].r + 1; x <= lis[i].x + lis[i].r - 1; x++)
{
for (int y = lis[i].y - lis[i].r + 1; y <= lis[i].y + lis[i].r - 1; y++)
{
if (x >= 0 && x <= n && y >= 0 && y <= m &&
gry[x][y] != lis[i].grey)
{
if(!(x - lis[i].x) * (x - lis[i].x) + (y - lis[i].y) * (y - lis[i].y) <= lis[i].r * 2)
{
printf("1\n");
}
f = false;
x = 1e9;
break;
}
}
}
// 绘制到图层
if (f)
{
SetWorkingImage(&now);
setfillcolor(RGB(lis[i].grey, lis[i].grey, lis[i].grey));
setlinecolor(RGB(lis[i].grey, lis[i].grey, lis[i].grey));
fillcircle(lis[i].x, lis[i].y, lis[i].r);
SetWorkingImage(NULL);
}
// 临时雪花图像
setfillcolor(RGB(lis[i].grey, lis[i].grey, lis[i].grey));
setlinecolor(RGB(lis[i].grey, lis[i].grey, lis[i].grey));
fillcircle(lis[i].x, lis[i].y, lis[i].r);
lis[i].grey = tmp;
lis[i].x += lis[i].dx;
lis[i].y += lis[i].dy;
if (lis[i].x<0 || lis[i].y>m)
{
lis.erase(lis.begin() + i);
}
}
FlushBatchDraw();
Sleep(10);
}
return 0;
}