【Win32绘图编程,GDI绘图对象】绘图基础,位图处理,绘图消息处理,画笔,画刷,文本绘制

news2024/11/5 22:50:45

这一篇文章分享本人学习win32绘图编程,其中包括GDI绘图对象,绘图基础,基本图形的绘制,画笔画刷的使用,文本绘制,以及文本字体的更改。

文章目录

  • 一.绘图基础
    • 1.BeginPaint函数
    • 2.EndPaint函数
    • 3.颜色的使用
  • 二.基本图形绘制
    • 1.点的绘制
      • `SetPixel`函数
      • 回调函数中处理绘图消息
    • 2.线的绘制
      • `MoveToEx`函数
      • `LineTo`函数
    • 3.封闭图形绘制
  • 三.GDI绘图对象--画笔
      • - 1.创建画笔
      • - 2.将画笔给到设备上下文(DC)
      • - 3.绘图
      • - 4.取出设备上下文(DC)中的画笔
      • - 5.释放画笔
  • 四.GDI绘图对象-画刷
  • 五.位图的使用
    • - 1.位图相关:
    • - 2.位图的使用
  • 六.文本绘制
  • 七.字体
    • 1.字体相关
    • 2.字体的使用

一.绘图基础

  • 绘图设备DC(Device Context),有时也叫做绘图上下文/绘图描述表/显示设备上下文
  • HDC-DC句柄,表示绘图设备
  • GDI-Windows graphics device interface (win32提供的绘图API)
  • 颜色:

    • RGB函数:
      • 红黄蓝按照一定比例配比,每个点颜色都是3个字节,24位保存,一共有0~2^24-1种
      • 16位操作系统通常使用三个参数来表示颜色,如:5,5,6
      • 32位操作系统通常使用4个参数来表示颜色,如:8,8,8,8.最后一个参数表示透明度
  • 绘图设备句柄:我们使用绘图设备,必须拿到绘图设备句柄

我们来想想这样一个场景:我们需要绘图,但是我们自己不会,我们把绘图设备比喻为一个画家,那么拿到绘图设备句柄的过程就相当于是把这个画家抓过来,抓过来让他完成工作后,还需要把画家放走。

PAINTSTRUCT ps = {0};              //在绘图之前,我们需要定义一个PAINTSTURCT结构体,我们不需要关注结构体内的内容
HDC hdc = BeginPaint(...);         //抓绘图设备句柄
TextOut(hdc,100,100,"Hello",...);  //绘制文本
EndPaint(...);         //释放绘图设备

我们来细讲一下BeginPaint函数和EndPaint函数:

1.BeginPaint函数

BeginPaint 函数准备用于绘制的指定窗口,并使用有关绘图的信息填充 PAINTSTRUCT 结构。
MSDN官方文档解释BeginPaint函数

HDC BeginPaint(
	HWND hWnd,
	LPPAINTSTRUCT lpPaintStruct
	);

其中,hWnd参数指定了要重新绘制的窗口句柄,lpPaintStruct指向我们定义的PAINTSTRUCT结构,这个函数会填上该结构中所需要的信息。

  • 返回值:如果创建成功,返回值是指定窗口的显示设备上下文的句柄,如果失败,返回NULL,指示没有显示设备上下文可用。

2.EndPaint函数

MSDN官方文档解释EndPaint函数
EndPaint函数标记指定窗口中绘制的结尾,每次调用BeginPaint函数时都需要此函数,但仅在绘制完成后才需要此函数。
语法:

BOOL EndPaint(
	HWND hWnd,          //已经重新绘制的窗口的句柄
	const PAINTSTRUCT* lpPaint    //指向包含BeginPaint检索的绘画信息的PAINTSTRUCT结构的指针
	);

返回值:返回值始终为非零值。
EndPaint函数释放BeginPaint函数检索道德显示设备上下文

3.颜色的使用

colorref–实际DWORD–using long
例如:
COLORREF nColor = 0;

赋值RGB宏:
例:
`nColor =RGB(0,0,255);

获取RGB的值:
GetRValue/GetGValue/GetBValue函数
例:
BYTE nRed = GetRValue(nColor);

二.基本图形绘制

1.点的绘制

SetPixel函数

MSDN官方文档解释SetPixel函数
SetPixel函数将指定坐标处的像素设置为指定颜色
函数原型:

COLORREF SetPixel(
	HDC hdc,      //设备上下文句柄
	int x,        //要设置的x坐标
	int y,        //要设置的y坐标
	COLORREF color        //用于绘制点的颜色
	);
  • 返回值:如果函数成功,则返回值为函数将像素设置为的RGB值。此值可能与crColor指定的颜色不同,当找不到指定颜色的完全匹配项时发生。如果函数失败,返回值为-1.

回调函数中处理绘图消息

这里给出的是所有的回调函数内容,大家可以翻到最后直接看绘制窗口消息处理过程。

LRESULT CALLBACK WindowProc(
	IN  HWND hwnd,
	IN  UINT uMsg,
	IN  WPARAM wParam,
	IN  LPARAM lParam
)
{
	char output[256] = { 0 };
	switch (uMsg)
	{
	//常见消息
	case WM_DESTROY: {
		PostQuitMessage(0);
		break;
		}
	case WM_SYSCOMMAND: {
		sprintf(output, TEXT("检测到WM_COMMAND消息\n"));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_CREATE: {
		sprintf(output, "检测到WM_CREATE消息,将创建窗口。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_SIZE: {
		sprintf(output, "lParam:窗口宽变化为:%d,窗口高变化为:%d \n", HIWORD(lParam), LOWORD(lParam));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	//菜单命令消息
	case WM_COMMAND: {
		switch(LOWORD(wParam)) {
			case MY_OPEN: {
				sprintf(output, "打开按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
			case MY_QUIT: {
				sprintf(output, "退出按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
			case IDM_ABOUT: {
				sprintf(output, "帮助按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
			}
			case MY_NEWFILE: {
				sprintf(output, "打开新文件按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
			case MY_LASTTIMEFILE: {
				sprintf(output, "上次打开文件按钮被点击,请到回调函数中做具体处理。\n");
				WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
				break;
			}
		}
		break;
	}
	//键盘消息
	case WM_KEYDOWN: {
		sprintf(output, "检测到WM_KEYDOWN消息,键码值:%d.\n", wParam);
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_KEYUP: {
		sprintf(output, "检测到WM_KEYUP消息,键码值:%d.该按键被放开\n", wParam);
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	//鼠标消息
	case WM_LBUTTONDOWN: {
		sprintf(output, "检测到WM_LBUTTONDOWN消息,鼠标左键被按下。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_LBUTTONUP: {
		sprintf(output, "检测到WM_LBUTTONUP消息,鼠标左键被放开。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output),0,0);
		break;
	}
	case WM_RBUTTONDOWN: {
		sprintf(output, "检测到WM_RBUTTON消息,鼠标右键被按下。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_RBUTTONUP: {
		sprintf(output, "检测到WM_RBUTTON消息,鼠标右键被放开。\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
	}
	case WM_MOUSEMOVE: {
		sprintf(output, "检测到WM_MOUSEMOVE消息,鼠标移动中,鼠标位置(%d,%d).\n", LOWORD(lParam), HIWORD(lParam));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_MOUSEWHEEL: {
		sprintf(output, "鼠标滚轮滚动中,偏移量:%d,鼠标当前位置(%d,%d)\n",HIWORD(wParam), LOWORD(lParam), HIWORD(lParam));
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		break;
	}
	case WM_CONTEXTMENU: {
		TrackPopupMenu(
		CreatePopupMenu(),
		TPM_LEFTALIGN,
		0, 0, 0, hwnd, 0);
		break;
	}
	//绘制窗口消息
	case WM_PAINT: {
		sprintf(output, "检测到WM_PAINT消息");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		PAINTSTRUCT ps = { 0 };
		HDC hdc = BeginPaint(hwnd, &ps);
		SetPixel(hdc, 100, 100, RGB(6, 8, 9));
		EndPaint(hwnd, &ps);
		break;
	}
	}
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

处理效果:
绘制点效果
大家可以看到程序中出现的点。由于是一个像素,可能看的不是很清楚。

2.线的绘制

像绘制点一样,我们也需要抓到设备上下文的句柄,画线,释放设备上下文。
在绘制线条的时候,我们需要几个函数,我们先来学习一下这几个函数:

MoveToEx函数

MSDN官方文档解释MoveToEx函数
MoveToEx函数将当前位置更新为指定点,并选择性地返回上一个位置。
语法:

BOOL MoveToEx(
	HDC hdc,        //设备上下文句柄
	int x,
	int y,          //指定当前点
	LPPOINT lppt    //指向接收当前位置的POINT指针,如果此参数为NULL指针,则不返回上一个位置
	);
  • 返回值:
    • 如果函数成功,则返回值为非零值
    • 如果函数失败,则返回值为0
  • 注释:MoveToEx函数将影响所有的绘图函数

LineTo函数

LineTo函数从当前位置绘制一行,但不包括指定点。
MSDN官方文档解释LineTo函数

BOOL LineTo(
	HDC hdc,          //设备上下文句柄
	int x,
	int y             //指定线条终点坐标
	);
  • 返回值:

    • 如果函数成功,返回值为非零值
    • 如果函数失败,返回值为零
  • 回调函数处理:

case WM_PAINT: {
		sprintf(output, "检测到WM_PAINT消息\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		PAINTSTRUCT ps = { 0 };
		HDC hdc = BeginPaint(hwnd, &ps);
		MoveToEx(hdc, 0, 0, NULL);
		LineTo(hdc, 500, 500);
		EndPaint(hwnd, &ps);
		break;
	}

处理效果:
绘制图形效果

3.封闭图形绘制

封闭图形:能够用画刷填充的图形
这里给出绘制矩形和绘制圆形的函数,其他函数有很多,大家可以自行学习

  • 绘制矩形:Rectangle函数
    Rectangle 函数绘制矩形。 该矩形使用当前笔轮廓,并使用当前画笔填充。
    MSDN官方文档解释Rectangle函数
BOOL Rectangle(
	HDC hdc,            //设备上下文句柄
	int left,
	int top,
	int right,
	int botton
);

回调函数处理:

	case WM_PAINT: {
		sprintf(output, "检测到WM_PAINT消息\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		PAINTSTRUCT ps = { 0 };
		HDC hdc = BeginPaint(hwnd, &ps);
	/*	MoveToEx(hdc, 0, 0, NULL);
		LineTo(hdc, 500, 500);*/
		Rectangle(hdc,100,100,200,200);
		EndPaint(hwnd, &ps);
		break;
	}

处理效果:
绘制矩形

  • 绘制圆形:Ellipse函数
  • 椭圆函数绘制椭圆。 椭圆的中心是指定边界矩形的中心。

MSDN官方文档解释Ellipse函数

BOOL Ellipse(
	HDC hdc,                  //设备上下文句柄
	int left,
	int top,
	int right,
	int bottom
	);

回调函数处理:

	case WM_PAINT: {
		sprintf(output, "检测到WM_PAINT消息\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		PAINTSTRUCT ps = { 0 };
		HDC hdc = BeginPaint(hwnd, &ps);
	/*	MoveToEx(hdc, 0, 0, NULL);
		LineTo(hdc, 500, 500);*/         //绘制直线
	//	Rectangle(hdc, 100, 100, 200, 200);    //绘制矩形
		Ellipse(hdc, 100, 100, 50, 50);        //绘制圆形
		EndPaint(hwnd, &ps);
		break;
	}

处理效果:
绘制圆形

三.GDI绘图对象–画笔

  • 画笔的作用:
    更改线条的颜色,线形,线粗。
  • 画笔句柄:HPEN

画笔的使用:
我们在上文中将设备上下文比喻为画家,在这里我们继续使用上文的比喻,能够帮助大家更好地理解。

- 1.创建画笔

CreatePen函数创建具有指定样式,宽度和颜色的逻辑笔。
MSDN官方文档解释CreatePen函数

HPEN CreatPen(
	int isStyle,          //笔样式
	int cWisth,           //笔的宽度
	COLORREF color        //笔的颜色
	);

注意: 笔样式中,PS_SOILD是实心线,可以支持多个像素宽度,其他线性只能是一个像素宽。

- 2.将画笔给到设备上下文(DC)

SelectObject 函数将对象选择到指定的设备上下文中, (DC) 。 新对象替换同一类型的上一个对象。
这一步骤相当于将创建好的新画笔给画家,让画家拿着我们创建的新画笔绘图。
MSDN官方文档解释SelectObject函数

SelectObject(
	HDC hdc,                //设备上下文句柄
	HGDIOBJ h               //GDI绘图对象句柄,画笔句柄
	);
  • 返回值:返回原来的GDI绘图对象句柄
    注意保存原来的GDI绘图对象句柄

- 3.绘图

这一步骤中使用绘图函数,绘制我们想要的图形

- 4.取出设备上下文(DC)中的画笔

在这一步骤中,将原来的画笔使用SelectObject函数,放入到设备上下文(DC)中,就会将我们的画笔取出

- 5.释放画笔

在绘图完成后,我们需要将我们的画笔释放:
MSDN官方文档解释SelectObject函数

BOOL SelectObject(
	HGDIOBJ ho            //逻辑笔,画笔,字体,位图,区域或调色板的句柄
	);

如果函数成功,返回非零值。
注意: 只能删除不被DC使用的画笔,所以在释放之前,必须将画笔从DC中取出。

我们来到回调函数中处理:

	case WM_PAINT: {
		sprintf(output, "检测到WM_PAINT消息\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		PAINTSTRUCT ps = { 0 };
		HDC hdc = BeginPaint(hwnd, &ps);
	/*	MoveToEx(hdc, 0, 0, NULL);
		LineTo(hdc, 500, 500);*/         //绘制直线
	//	Rectangle(hdc, 100, 100, 200, 200);    //绘制矩形
		HPEN hPen = CreatePen(PS_SOLID, 3, RGB(50, 80, 99));
		HGDIOBJ hOldPen = SelectObject(hdc, hPen);
		Ellipse(hdc, 100, 100, 50, 50);        //绘制圆形
		EndPaint(hwnd, &ps);
		SelectObject(hdc, hOldPen);
		DeleteObject(hOldPen);
		break;
	}

我们看看处理效果:
画笔应用

四.GDI绘图对象-画刷

  • 作用:封闭图形填充的颜色,图案
  • 画刷句柄:HBRUSH

画刷的使用:

  • 1.创建画刷
    CreateSoildBrush函数:创建实心画刷
    CreateHatchBrush函数:创建纹理画刷
  • 2.将画刷应用到DC中
  • 3.绘图
  • 4.将画刷从DC中取出
  • 5.删除画刷

我们看看回调函数处理过程:

	case WM_PAINT: {
		sprintf(output, "检测到WM_PAINT消息\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		PAINTSTRUCT ps = { 0 };
		HDC hdc = BeginPaint(hwnd, &ps);
	/*	MoveToEx(hdc, 0, 0, NULL);
		LineTo(hdc, 500, 500);*/         //绘制直线
	//	Rectangle(hdc, 100, 100, 200, 200);    //绘制矩形
		HPEN hPen = CreatePen(PS_SOLID, 3, RGB(50, 80, 99));
		HGDIOBJ hOldPen = SelectObject(hdc, hPen);
		HGDIOBJ hBrush = CreateSolidBrush(RGB(255, 0, 0));
		HGDIOBJ hOldBrush = SelectObject(hdc, hBrush);
		SelectObject(hdc, hBrush);
		Ellipse(hdc, 100, 100, 50, 50);        //绘制圆形
		EndPaint(hwnd, &ps);
		SelectObject(hdc, hOldPen);
		SelectObject(hdc, hOldBrush);
		DeleteObject(hPen);
		DeleteObject(hBrush);
		break;
	}

我们来看看处理效果:
画刷应用

五.位图的使用

- 1.位图相关:

光栅图形:记录图像中每一个点的颜色信息
矢量图形:记录图像算法,绘图指令等

  • 位图句柄:HBITMAP

- 2.位图的使用

  • 1.可视化图形界面添加位图资源:
    添加位图资源
    添加好之后,将我们需要的位图导入或我们自己画一个,在文章中我自己画一个:
    画位图
  • 2.从资源中加载位图
    LoadBitmap函数:
    LoadBitmap 函数从模块的可执行文件加载指定的位图资源。
    MSDN官方文档解释LoadBitmap函数
LoadBitmap(
	HINSTANCE hInstance,            //其可执行文件包含要加载的位图模块实例的句柄
	LPSTR lpBitmapName              //指向包含要加载的位图资源名称的空终止字符串的指针
	);
  • 返回值:如果函数成功,则返回指定位图的句柄

  • 3.创建一个与当前DC相匹配的DC(内存DC)

HDC CreateCompatibleDC(
	HDC hdc            //当前DC句柄,可以为NULL(屏幕DC)
	);创建成功,返回DC句柄
  • 4.将为图放入匹配DC中(SeleteObject函数)
  • 5.成像:
    这里指示简单介绍了一个1:1成像的函数,其他函数可以自行查找
    BitBle函数
    MSDN官方文档解释BitBle函数
BOOL BitBlt(
	HDC hdc,              //目标设备上下文句柄
	int x,                //目的矩形左上角x坐标
	int y,                //目的矩形左上角y坐标
	int cx,               //源矩形和目标矩形的宽度
	int cy,               //源矩形和目标矩形的高度
	HDC hdcsrc,           //源设备上下文句柄
	int x1,               //源矩形左上角的x坐标
	int y1,               //源矩形左上角的y坐标
	DWORD ROP             //光栅操作代码
	);如果函数成功,则返回非零值
  • 6.取出位图SeleteObject函数
  • 7.释放位图DeleteObject函数
  • 8.释放匹配DC

我们来到回调函数中处理:

	//绘制窗口消息
	case WM_PAINT: {
		sprintf(output, "检测到WM_PAINT消息\n");
		WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
		PAINTSTRUCT ps = { 0 };
		HDC hdc = BeginPaint(hwnd, &ps);
	/*	MoveToEx(hdc, 0, 0, NULL);
		LineTo(hdc, 500, 500);*/         //绘制直线
	//	Rectangle(hdc, 100, 100, 200, 200);    //绘制矩形
		/*HPEN hPen = CreatePen(PS_SOLID, 3, RGB(50, 80, 99));
		HGDIOBJ hOldPen = SelectObject(hdc, hPen);
		HGDIOBJ hBrush = CreateSolidBrush(RGB(255, 0, 0));
		HGDIOBJ hOldBrush = SelectObject(hdc, hBrush);
		SelectObject(hdc, hBrush);
		Ellipse(hdc, 100, 100, 50, 50);        //绘制圆形
		EndPaint(hwnd, &ps);
		SelectObject(hdc, hOldPen);
		SelectObject(hdc, hOldBrush);
		DeleteObject(hPen);
		DeleteObject(hBrush);*/
		//位图:
		HBITMAP hBitmap = LoadBitmap(hIns, (LPCSTR)IDB_BITMAP1);   //加载位图
		HDC hNewHdc = CreateCompatibleDC(hdc);       //创建与当前DC匹配的内存DC
		HGDIOBJ hOldBitmap = SelectObject(hNewHdc, hBitmap);
		BitBlt(hdc, 100, 100, 100,100, hNewHdc, 0, 0, SRCCOPY);
		SelectObject(hNewHdc, hOldBitmap);
		DeleteObject(hBitmap);
		DeleteDC(hNewHdc);
		break;
	}

我们来看看处理效果:
位图应用
这里我们只是将位图1:1成像,大家可以使用其他方法,使程序更加美观。

六.文本绘制

文字绘制:

  • TextOut函数:功能不是很强大,我们今天来学习一种更加强大的函数:
  • DrawText函数
    MSDN官方文档解释DrawText函数
int DrawText(
	HDC hdc,                   //设备上下文句柄
	LPCTSTR lpchText,          //指向指定要绘制的文本的字符串的指针
	int cchText,               //字符串的长度
	LPRECT lprc,               //指向RECT结构的指针
	UINT format                //设置文本格式的方法
	);
  • 文字颜色以及背景的设置:
    • 文字颜色SetTextColor函数
    • 文字背景颜色:SetBkColor函数(只有在OPAQUE模式下适用)
    • 文字背景模式:SetBkMode函数,其中参数设置为OPANQUE(不透明),TRANSPARENT(透明)

七.字体

1.字体相关

  • 字体文件路径:一般在C:\Windows\Fonts目录下
    字体文件
  • Windows常用字体为TrueType格式字体
  • 字体名:标识字体类型,注意这里的字体名要以文件中的字体名为准:
    字体名

2.字体的使用

  • 1.使用CreateFont函数到硬盘查找字体文件
    MSDN官方文档解释CreateFont函数
    • 函数功能:CreateFont函数创建具有指定特征的逻辑字体
    • 语法:
HFONT CreateFintA(
	int cHeight,              //字体字符单元格时或字符的高度
	int cWidth,               //请求字体中字符的平均宽度
	int cEscapement,          //转义向量与设备x轴之间的角度
	int cOrientation,         //每个字符的基线与设备x轴之间的角度
	int cWeight,              //字体粗细值(0到1000)
	DWORD bItalic,            //如果设置为TRUE 则指定斜体
	DWORD bUnderline,         //如果指定为TRUE,则指定带下划线字体
	DWORD bStrikeOut,         //如果设置为TRUE,则为删除线字体
	DWORD iCharSet,           //字符集
	DWORD iOutPracision,      //输出精度
	DWORD iClipPrecision,     //剪辑精度
	DWORD iQuality,           //输出质量
	DWORD iPitchAndFamily,    //字体的音调和系列
	LPCSTR pszFaceName        //指向指定字体字号的 null 终止字符串的指针
	);
  • 2.应用字体到DC(使用SelectObject函数)
  • 3.绘制字体文字(DrawText/TextOut函数)
  • 4.取出字体(SeleteObject函数)
  • 5.删除字体

本篇文章就分享到这里,大家如果有什么不理解的随时可以私信我,如果发现文章中的问题,希望大家及时指出来,我会非常虚心地学习,希望我们共同进步!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/508782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8 集群管理

8 集群管理 8.1 集群结构 ES通常以集群方式工作,这样做不仅能够提高 ES的搜索能力还可以处理大数据搜索的能力,同时也增加了系统的容错能力及高可用,ES可以实现PB级数据的搜索。 下图是ES集群结构的示意图: 从上图总结以下概念…

SSM整合详细教学(下)

SSM整合详细教学(下) 五、SSM整合页面开发1 准备工作2 列表查询功能3 添加功能4 修改功能5 删除功能 六、拦截器1 拦截器简介问题导入1.1 拦截器概念和作用1.2 拦截器和过滤器的区别 2 入门案例问题导入2.1 拦截器代码实现【第一步】定义拦截器【第二步】…

从零开始搭建高效的文件服务器:FastDFS与Nginx完美结合,内网穿透实现公网访问

目录 前言 1. 本地搭建FastDFS文件系统 1.1 环境安装 1.2 安装libfastcommon 1.3 安装FastDFS 1.4 配置Tracker 1.5 配置Storage 1.6 测试上传下载 1.7 与Nginx整合 1.8 安装Nginx 1.9 配置Nginx 2. 局域网测试访问FastDFS 3. 安装cpolar内网穿透 4. 配置公网访问…

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归时间序列区间预测

区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归时间序列区间预测 目录 区间预测 | MATLAB实现QRBiLSTM双向长短期记忆神经网络分位数回归时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 进阶版 基础版 基本介绍 MATLAB实现QRBiLS…

C语言介绍

C语言的简洁 C语言仅有32个关键字、9种控制语句、34种运算符即可实现无数的功能。 关键字 可省略的关键字:auto、extern、signed. 复合类型的关键字:enum、struct、union. include include表示导入,include可以导入任意的文件。 比如#in…

Windows消息,消息循环的处理,消息队列,键盘消息,鼠标消息,定时器消息

上一章节中我们带大家编写了第一个Windows程序,并且带大家学习了注册窗口,创建窗口,这一章中我们来学习Windows消息,学习对消息循环处理的原理,并且带领大家学习一些常见的消息。 文章目录 一.消息基础1.消息概念及其作…

AOF 持久化详解

文章目录 AOF 相关配置AOF 文件的修复AOF 文件格式RESP 协议查看 AOF 文件清单文件 AOF RewriteRewrite 策略手动Rewrite自动Rewrite AOF 持久化过程AOF优缺点AOF与RDB混合持久化 AOF (Append Only File) 是把所有对内存进行修改的指令(写操作)以独立日志…

《花雕学AI》用AI创造清晨的美好:ChatGPT+DALL-E 2 生成“早上好”的场景图

早晨是一天中最美好的时刻,也是最适合与AI对话的时刻。想象一下,当你醒来,打开手机,就能看到一个AI为你生成的“早上好”的场景图,是不是很温馨?这就是ChatGPTDALL-E 2(新Bing) 的魅…

Elevate:全世界最小的介入泵,融资五千万美金

近日,以色列医疗器械公司Magenta Medical宣布完成5500万美元的C轮融资,该公司主要产品Elevate是目前全球最小的心脏介入泵,主要用于治疗急性心力衰竭患者和高危PCI的辅助。该泵采用了创新的设计和材料,可以通过桡动脉插入&#xf…

哪款远程控制软件可以远程玩游戏?

远程控制软件可以让你在不同设备之间进行远程控制。许多人可能会想知道,哪款远程控制软件可以在远程玩游戏时享受更好的游戏体验。 首先,在寻找适合远程游戏的远程控制软件之前,我们需要知道什么是远程游戏和远程控制。 远程游戏是一种允许玩…

第十二章_Redis单线程 VS 多线程

Redis为什么选择单线程? 是什么 这种问法其实并不严谨,为啥这么说呢? Redis的版本很多3.x、4.x、6.x,版本不同架构也是不同的,不限定版本问是否单线程也不太严谨。 1 版本3.x ,最早版本,也就是大家口口相…

一文读懂 DNS 解析

导读 文章为“一文读懂域名与网站系列”第二篇,上篇文章主要介绍了域名的注册、建站和管理,通过本文你可以了解以下几个问题: 域名的结构、常用解析记录的类型 DNS 解析的过程 DNS 解析拓展知识 众所周知,互联网中的地址其实是…

想让行车记录仪协助道路病害自动化检测?可以!

针对【RGB3DS道路表观病害信息智慧检测系统】,我们着重介绍过其与道路检测车做集成预装或者处理道路检测车数据的极大便利,其中之一便是可高效输出带有道路检测车桩号标记的病害报表,这是因为道路检测车数据本身具有规范性。 那么如果使用道…

Linux(类Unix)系统可执行程序ELF文件格式详解

我们知道一个Linux程序饱和程序代码和初始数据,那么这些程序二进制代码和初始数据在可执行程序文件中是怎么进行存储呢?这便是ELF文件格式要解决的问题。 一个Linux执行程序的内存结构粗略可划分为 代码段、数据段、BSS、堆、栈,如下图所示&…

Golang Gin 使用路由分类处理请求

在前面已经学习了gin框架如何处理请求,解析请求,返回数据。 在实际的项目当中,项目往往是以模块化来进行划分和开发的,所谓的模块化就是按照功能来划分,比如会有产品模块,会有用户模块,会将用户…

如何用ChatGPT协助搭建品牌视觉体系(VI)?

该场景对应的关键词库(18个): VI体系、品牌、目标市场、品牌DNA、人群特征、设计理念、标志设计、配色方案、字体选择、图形元素、价值观、形象、客户经理、需求、品牌定位、目标受众、主色调、辅助色 提问模板(2个)&…

并发编程09:ThreadLocal

文章目录 9.1 ThreadLocal简介9.1.1 面试题9.1.2 是什么?9.1.3 能干吗?9.1.4 API介绍9.1.5 永远的helloworld讲起9.1.6 总结 9.2 ThreadLocal源码分析9.2.1 源码解读9.2.2 Thread、ThreadLocal、ThreadLocalMap关系9.2.3 总结 9.3 ThreadLocal内存泄漏问…

基于html+css的图展示53

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

网络:TCP协议三次握手与四次挥手

一、理解TCP报文 TCP报文格式_TCP报文包含哪些内容: TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。 TCP在发送数据前必须在彼此间建立连接,这里连接意思是:双方需要内保存对方信息(例如&…

leecode100_第7题接雨水_双指针

1 题目 2 分析 简述:两个指针分别指向两端,通过判断柱子的升降趋势来判断是否可以接水。 思路如下: 变量l_max,r_max分别记录当前时刻,左右遍历过的柱子的最高的高度,因为它奠定了水能积多高。分情况判断&#xff1a…