前言
前面几篇文章在编写代码过程中,获取一张图像的坐标和颜色,使用的是画图和PicPick这两个软件,虽然能够完成我们需要的功能,但是来回切换,并且要记忆坐标值,非常的麻烦。为了方便在编程过程中快速便捷的获取图片中的坐标和颜色,特此开发Easyx辅助器。
开发思路
首先开始用一个按钮打开图片,通过获取图片的大小来确定窗口的大小。为了在使用的时候方便,我们将这个窗口永久置顶。然后修改一下鼠标的样式为十字形。
鼠标在图片上获取坐标,并且求解所在坐标的颜色值,然后输出到图片上。
编程心得
在编写代码过程中,我基本上是只有一个大概的思路,其他的就是顺势而为。我看网上好多辅导机构教小学生编程,这是一个很好的开头,但是宣传视频有点违背了编程的初衷,编程是为了解决问题,而不是应付一次考试。我看到孩子们在编程过程中几乎不思考,只是机械的快速的敲击键盘,像是背课文似的。
我从来刻意不记忆代码,有的东西只记个大概,然后在编写过程中一点点拼凑。将平时积累的代码复制粘贴,程序片段是用的,而不是背的。就比如我想要一个打开一个文件夹的函数,我就想起来我以前写的哪个程序中写有,去复制粘贴过来,再比如,我想知道一个颜色取反如何计算,去问一下AI就行。
我们要做的就是保持自己的想象力,创造力,然后使用编程这个工具去实践。
源码
///////////////////////////////////////////////////
// 程序名称: EasyX辅助器
// 编译环境:Mictosoft Visual Studio 2022, EasyX_20211109
// 作 者:luoyh <2864292458@qq.com>
// 最后修改:2024-9-5
// 公 众 号:C语言研究
//
int OpenPhoto(char szFile[]);
void DrawF(); // 绘制界面
int FileDialog(char* path); // 添加图片
void LoadIMG(char szFile[]); // 加载图片
int GetPC(); // 获取颜色和坐标
void DrawTXT(int x, int y); // 获取这个坐标的位置信息和颜色
int main()
{
char szFile[MAX_PATH] = { 0 };
OpenPhoto(szFile); // 打开图片按钮界面
while (true)
{
LoadIMG(szFile); // 加载图片并且使得窗口永远置顶
GetPC();
}
_getch();
return 0;
}
void DrawF()
{
initgraph(640, 480);
setbkcolor(BLACK);
cleardevice();
setbkmode(TRANSPARENT);
settextcolor(WHITE);
settextstyle(50, 0, _T("楷体"));
RECT r = { 0, 0, 640, 200 };
drawtext(_T("EasyX辅助器"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
setlinecolor(WHITE);
setlinestyle(PS_SOLID, 3);
roundrect(210, 200, 430, 250, 10, 10);
RECT r1 = { 0, 200, 640, 250 };
drawtext(_T("加载图片"), &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
roundrect(210, 280, 430, 330, 10, 10);
RECT r2 = { 0, 280, 640, 330 };
drawtext(_T("使用说明"), &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
int OpenPhoto(char szFile[])
{
DrawF();
// 获取鼠标消息判断
ExMessage m; // 定义消息变量
while (true)
{
// 获取一条鼠标或按键消息
m = getmessage(EX_MOUSE | EX_KEY);
switch (m.message)
{
case WM_LBUTTONDOWN:
if (m.x > 210 && m.x < 430 && m.y>200 && m.y < 250)
{
if (!FileDialog(szFile))
{
MessageBox(NULL, "不合法路径", "错误", MB_OK);
DrawF();
}
else
{
return 0;
}
// 加载图片
}
if (m.x > 210 && m.x < 430 && m.y>280 && m.y < 330)
{
// 使用说明
cleardevice();
RECT r = { 0, 0, 640, 480 };
drawtext(_T("开发中。。。按任意键继续"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
_getch();
DrawF();
}
break;
}
}
}
int FileDialog(char* path)
{
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); // 结构大小
ofn.lpstrFile = path;
ofn.nMaxFile = MAX_PATH; // 路径大小
ofn.lpstrFilter = TEXT("图片文件(bmp;jpg;png)\0*.bmp;*.jpg;*.png;*.tiff;*.gif;*.tif;*jpeg\0\0"); // 文件类型
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
return GetOpenFileName(&ofn);
}
void LoadIMG(char szFile[])
{
IMAGE img;
loadimage(&img, szFile);
int width = img.getwidth();
int height = img.getheight();
HWND hWnd = initgraph(width, height);
// 将窗口永远置于顶部
putimage(0, 0, &img);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
HCURSOR hcur = LoadCursor(NULL, IDC_CROSS); // 加载系统预置的鼠标样式
SetClassLongPtr(hWnd, GCLP_HCURSOR, (long)hcur); // 设置窗口类的鼠标样式
}
int GetPC()
{
ExMessage m; // 定义消息变量
while (true)
{
// 获取一条鼠标或按键消息
m = getmessage(EX_MOUSE | EX_KEY);
switch (m.message)
{
case WM_LBUTTONDOWN: // 左键获取
DrawTXT(m.x, m.y);
break;
case WM_RBUTTONDOWN: // 右键清空绘制
return 1;
}
}
}
void DrawTXT(int x, int y)
{
TCHAR str[25];
COLORREF Color = getpixel(x, y);
int R = GetRValue(Color);
int G = GetGValue(Color);
int B = GetBValue(Color);
setrop2(R2_MASKPENNOT);
setlinecolor(RGB(255 - R, 255 - G, 255 - B));
circle(x, y, 5); // 圆圈颜色取反
_stprintf_s(str, _T("<%d,%d><%d,%d,%d>"), x, y, R, G, B);
settextcolor(RGB(255 - R, 255 - G, 255 - B));
setbkmode(TRANSPARENT);
settextstyle(15, 0, _T("宋体"));
if (x + 100 > getwidth())
{
outtextxy(x - 150, y + 2, str);
}
else if (y + 20 > getheight())
{
outtextxy(x - 2, y - 20, str);
}
else
{
outtextxy(x + 2, y + 2, str);
}
}
效果演示
编写过程