easyX库图像处理相关函数

news2024/11/15 15:57:14

0.图像处理相关函数与类型概览

您好,这里是limou3434,本次我将给您带来的是easyX的图像处理相关接口。

如果您感兴趣也可以看看我的其他内容。

函数或数据类型描述
IMAGE保存图像的对象。
loadimage读取图片文件。
putimage在当前绘图设备上绘制指定图像。
rotateimage旋转 IMAGE 中的绘图内容。
Resize调整指定绘图设备的尺寸。
getimage从当前绘图设备中获取图像。
saveimage保存绘图内容至图片文件。
SetWorkingImage设定当前绘图设备。
GetWorkingImage获取指向当前绘图设备的指针。
GetImageBuffer获取绘图设备的显示缓冲区指针。
GetImageHDC获取绘图设备句柄。

1.IMAGE:图像对象

图像类使用的是C++的class类关键字创建的,可以依靠图像类创建出图像对象。(您可以把class理解成升级版的struct,里面不仅有成员变量,还能放入成员函数)

class IMAGE(int width = 0, int height = 0);
//公有成员内的函数
//int getwidth():返回IMAGE对象的宽度,以像素为单位
//int getheight():返回IMAGE对象的高度,以像素为单位
//operator=:实现IMAGE对象的直接赋值。该操作仅拷贝源图像的内容,不拷贝源图像的绘图环境。这是赋值运算符重载,可以使得两个图像对象进行赋值操作

2.loadimage:读取图片文件

loadimage()是配合上述的对象使用的函数,该函数可以读取一个图片文件,并让IMAGE类型的指针指向该图片文件。该函数也有重载版本,有两种用法。

//从图片文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico)
void loadimage(
	IMAGE* pDstImg,			//保存图像的IMAGE对象指针
	LPCTSTR pImgFile,		//图片文件名
	int nWidth = 0,			//图片的拉伸宽度
	int nHeight = 0,		//图片的拉伸高度
	bool bResize = false	//是否调整IMAGE的大小以适应图片
);
//从资源文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico)
void loadimage(
	IMAGE* pDstImg,			//保存图像的IMAGE对象指针
	LPCTSTR pResType,		//资源类型
	LPCTSTR pResName,		//资源名称
	int nWidth = 0,			//图片的拉伸宽度
	int nHeight = 0,		//图片的拉伸高度
	bool bResize = false	//是否调整IMAGE的大小以适应图片
);

//参数
//pDstImg:保存图像的IMAGE对象指针。如果为NULL,表示图片将读取至绘图窗口
//pImgFile:图片文件名。支持bmp/gif/jpg/png/tif/emf/wmf/ico 格式的图片。gif格式的图片仅加载第一帧;gif与png均不支持透明
//nWidth:图片的拉伸宽度。加载图片后,会拉伸至该宽度。如果为0,表示使用原图的宽度
//nHeight:图片的拉伸高度。加载图片后,会拉伸至该高度。如果为0,表示使用原图的高度。
//bResize:是否调整IMAGE的大小以适应图片
//pResType:图片资源类型
//pResName:图片资源名称

//返回值
//无

2.1.图片格式

需要注意的是loadimage()支持大部分的图片格式:bmp、gif、jpg、png、tif、emf、wmf、ico。这里我整理了一下有关图片格式的相关内容供您查阅:

  1. BMP(Bitmap):
  • 包含未经压缩的图像数据,文件大小较大。
  • 支持多种颜色模式和图像深度。
  • 适用于存储位图和图形编辑软件中的临时图像。
  1. GIF(Graphics Interchange Format):
  • 使用LZW压缩算法来减小文件大小。
  • 支持使用索引颜色的图像,最多仅支持256种颜色。
  • 支持动画和透明背景。
  • 适用于简单的图标、动画、线条图等具有明确边界和较少颜色的图像。
  1. JPG或JPEG(Joint Photographic Experts Group):
  • 使用有损压缩算法以较小的文件大小存储图像。
  • 支持全彩色图像和较高的图像质量。
  • 不支持透明背景和动画。
  • 适用于摄影、复杂图像和需要保持良好质量的图像。
  1. PNG(Portable Network Graphics):
  • 使用无损压缩算法以较小的文件大小存储图像。
  • 支持全彩色图像、透明背景和图像的部分alpha通道。
  • 不支持动画。
  • 适用于图标、图形设计、网页图像和需要保留透明度的图像。
  1. TIFF(Tagged Image File Format):
  • 支持多种压缩算法,可以选择有损或无损压缩。
  • 支持全彩色图像、多页文档和多帧动画。
  • 文件大小较大,不适合网络传输。
  • 适用于打印、出版业、医学图像等需要高质量图像和元数据的场景。
  1. EMF(Enhanced Metafile)和WMF(Windows Metafile):
  • 为矢量图形格式,可缩放而不失真。
  • EMF是Windows特定的增强型元文件格式,支持更多功能。
  • WMF是旧版的Windows元文件格式。
  • 适用于矢量图形、图表、图标、绘图程序等需要保持较好清晰度和编辑能力的场景。
  1. ICO(Icon):
  • 用于存储图标文件,通常用于Windows操作系统。
  • 支持多种尺寸的图标图像。
  • 适用于自定义应用程序图标、网站图标等。

在上述图片格式中,您最需要了解的图片格式是GIF、PNG、JPG/JPEG,因为这是最常用的图片格式,其他仅作了解即可。

2.2.图像文件获取和资源文件获取的区别

从资源文件获取这个暂时还用不到,先跳过,这里先展示图像文件获取的例子:

#include <graphics.h>
#include <cstdio>
int main()
{
	//绘图窗口初始化
	initgraph(1000, 1000, EX_SHOWCONSOLE);

	//读取图片至绘图窗口
	loadimage(NULL, _T("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\testPicture2.jpg"), 0, 0, true);//这里填写您图片的路径即可
	getchar();

	//关闭绘图窗口
	closegraph();
	getchar();
	return 0;
}

在这里插入图片描述

3.putimage:在当前绘图设备上绘制指定图像

我们可以通过loadimage()读取图片,然后存储到IMAGE类型的对象中,在后续需要输出图片的时候使用putimage()输出图片。

//绘制图像
void putimage(
	int dstX,				//绘制位置的x坐标
	int dstY,				//绘制位置的y坐标
	IMAGE *pSrcImg,			//要绘制的IMAGE对象指针
	DWORD dwRop = SRCCOPY	//三元光栅操作码
);
//绘制图像(指定宽高和起始位置)
void putimage(
	int dstX,				//绘制位置的x坐标
	int dstY,				//绘制位置的y坐标
	int dstWidth,			//绘制的宽度
	int dstHeight,			//绘制的高度
	IMAGE *pSrcImg,			//要绘制的IMAGE对象指针
	int srcX,				//绘制内容在IMAGE对象中的左上角 x 坐标
	int srcY,				//绘制内容在IMAGE对象中的左上角 y 坐标
	DWORD dwRop = SRCCOPY	//三元光栅操作码
);

这里的三元光栅操作码我们以后再谈……

//使用例子
#include <graphics.h>
#include <cstdio>
int main()
{
	//绘图窗口初始化
	int length = 1000;
	int width = 1000;
	initgraph(length, width, EX_SHOWCONSOLE);

	//坐标轴修正
	setaspectratio(1, -1);
	setorigin(length / 2, width / 2);

	//读取图片至绘图对象
	IMAGE img1;
	loadimage(
		&img1,
_T("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\testPicture2.jpg")
	);
	putimage(0, 0, &img1);
	getchar();

	//关闭绘图窗口
	closegraph();
	return 0;
}

在这里插入图片描述

4.rotateimage:旋转IMAGE中的绘图内容

在上面的图片输出中我们可以看到,easyX库对图片方向的输出是有自己的默认规则的,想要选择只能通过rotateimage()来选择,而不能旋转图片文件。

void rotateimage(
	IMAGE *dstimg,
	IMAGE *srcimg,
	double radian,
	COLORREF bkcolor = BLACK,
	bool autosize = false,
	bool highquality = true
);
//参数
//dstimg:指定目标IMAGE对象指针,用来保存旋转后的图像
//srcimg:指定原IMAGE对象指针
//radian:指定旋转的弧度
//bkcolor:指定旋转后产生的空白区域的颜色。默认为黑色
//autosize:指定目标IMAGE对象是否自动调整尺寸以完全容纳旋转后的图像。默认为false
//highquality:指定是否采用高质量的旋转。在追求性能的场合请使用低质量旋转。默认为true

这个函数也比较简单,下面给您展示一下使用的例子:

//使用例子
#include <graphics.h>
#include <cstdio>
int main()
{
	//绘图窗口初始化
	int length = 1000;
	int width = 1000;
	initgraph(length, width, EX_SHOWCONSOLE);

	//坐标轴修正
	setaspectratio(1, -1);
	setorigin(length / 2, width / 2);

	//读取图片至绘图对象
	IMAGE img1;
	loadimage(
		&img1,
		_T("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\testPicture2.jpg")
	);
	putimage(0, 0, &img1);
	getchar();

	//旋转后
	IMAGE img2;
	rotateimage(&img2, &img1, 3.14/2);
	putimage(-500, -500, &img2);
	getchar();

	//关闭绘图窗口
	closegraph();
	return 0;
}

5.Resize:调整指定绘图设备的尺寸

注意这里的调整尺寸指的是裁剪尺寸不是缩放后的尺寸。

void Resize(
	IMAGE* pImg,
	int width,
	int height
);
//参数
//pImg:指定要调整尺寸的绘图设备。如果为NULL,则表示默认绘图窗口。
//width:指定绘图设备的宽度。
//height:指定绘图设备的高度。

//返回值
//无

下面以一个例子来说明:

//使用例子
#include <graphics.h>
#include <cstdio>
int main()
{
	//绘图窗口初始化
	int length = 1000;
	int width = 1000;
	initgraph(length, width, EX_SHOWCONSOLE);

	//读取图片至绘图对象
	IMAGE img1;
	loadimage(
		&img1,
		_T("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\testPicture2.jpg")
	);
	putimage(0, 0, &img1);
	getchar();

	//调整好大小后
	Resize(&img1, 500, 500);
	putimage(100, 100, &img1);
	getchar();
		
	closegraph();
	return 0;
}

在这里插入图片描述

6.getimage:从当前绘图设备中获取图像

这个函数可以实现在当前设备中裁剪图像区域并且实现复制图像区域的效果。

void getimage(
	IMAGE* pDstImg,		//保存图像的IMAGE对象指针
	int srcX,			//要获取图像区域左上角x坐标
	int srcY,			//要获取图像区域的左上角y坐标
	int srcWidth,		//要获取图像区域的宽度
	int srcHeight		//要获取图像区域的高度
);

下面就一个例子来演示这个函数的使用:

//使用例子
#include <graphics.h>
#include <cstdio>
int main()
{
	//绘图窗口初始化
	int length = 1000;
	int width = 1000;
	initgraph(length, width, EX_SHOWCONSOLE);

	//读取图片至绘图对象
	IMAGE img1;
	loadimage(
		&img1,
		_T("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\testPicture2.jpg")
	);
	putimage(0, 0, &img1);
	getchar();

	//旋转后
	IMAGE img2;
	rotateimage(&img2, &img1, 3.14/2, WHITE);
	putimage(0, 0, &img2);
	getchar();

	//复制区域的图像并且输出
	IMAGE img3;
	getimage(&img3, 200, 200, 300, 300); 
	putimage(0, 0, &img3);
	getchar();

	closegraph();
	return 0;
}

因此上面这段代码的结果如下:
在这里插入图片描述

7.saveimage:保存绘图内容至图片文件

void saveimage(
	LPCTSTR strFileName,
	IMAGE* pImg = NULL
);
//参数
//strFileName:指定目标图片的文件名。图片类型由文件名的扩展名指定,支持bmp/gif/jpg/png/tif 格式。保存文件时,已存在的文件将被覆盖。
//pImg:指定源IMAGE对象的指针。如果为NULL,表示绘图窗口。

//返回值
//无

让我们尝试保存刚刚绘画得到的图像:

//使用例子
#include <graphics.h>
#include <cstdio>
int main()
{
	//绘图窗口初始化
	int length = 1000;
	int width = 1000;
	initgraph(length, width, EX_SHOWCONSOLE);

	//读取图片至绘图对象
	IMAGE img1;
	loadimage(
		&img1,
_T("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\testPicture2.jpg")
	);
	putimage(0, 0, &img1);
	getchar();

	//旋转后
	IMAGE img2;
	rotateimage(&img2, &img1, 3.14/2, WHITE);
	putimage(0, 0, &img2);
	getchar();

	//复制区域的图像并且输出
	IMAGE img3;
	getimage(&img3, 200, 200, 300, 300); 
	putimage(0, 0, &img3);
	getchar();

	//保存图像
	saveimage("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\img.jpg");

	closegraph();
	return 0;
}

8.SetWorkingImage:设定当前绘图设备

如需要对某个IMAGE做绘图操作,可以通过SetWorkingImage()将其设置为当前的绘图设备,之后所有的绘图语句都会绘制在该IMAGE上面。将参数置为 NULL 可恢复对默认绘图窗口的绘图操作。

void SetWorkingImage(IMAGE* pImg = NULL);
//参数
//pImg:绘图设备指针。如果为NULL,表示绘图设备为默认绘图窗口。

//返回值
//无

下面举一个例子来说明SetWorkingImage()的使用:

//使用例子 
#include <graphics.h> 
#include <cstdio> int main() 
{
  	//绘图窗口初始化 
  	int length = 1000; 
  	int width = 1000; 
  	initgraph(length, width, EX_SHOWCONSOLE); //读取图片至绘图对象 
  	IMAGE img1; 
 	loadimage( &img1, _T("C:\\Users\\DELL\\Desktop\\SummerHolidaysFile\\GSnakeEasyxProject\\testPicture2.jpg") );
  	putimage(0, 0, &img1); 
  	getchar(); //以下绘图操作都会绘制在img1对象上面 
  	line(0 + 100, 100, 200 + 100, 100); 
  	line(100 + 100, 0, 100 + 100, 200);
  	circle(100 + 100, 100, 50); //设置绘图目标为img1对象
  	SetWorkingImage(&img1);
  	printf("img1\n"); 
  	getchar(); //设置绘图目标为绘图窗口 
  	SetWorkingImage();
  	line(0, 100, 200, 100); 
  	line(100, 0, 100, 200); 
  	circle(100, 100, 50); 
  	printf("绘图窗口\n"); 
  	getchar(); 
  	closegraph();
  	return 0; 
}

在这里插入图片描述

9.GetWorkingImage:获取指向当前绘图设备的指针

IMAGE* GetWorkingImage();
//参数
//无

//返回值
//返回指向当前绘图设备的指针。如果返回值为NULL,表示当前绘图设备为绘图窗口。

10.GetImageBuffer:获取绘图设备的显示缓冲区指针

这个函数比较强大,能够做到很微小的像素改动。

DWORD* GetImageBuffer(IMAGE* pImg = NULL);
//参数
//pImg:绘图设备指针。如果为 NULL,表示默认的绘图窗口。

//返回值
//返回绘图设备的显示缓冲区指针。

获取到的显示缓冲区指针可直接读写。在显示缓冲区中每个点占用4个字节(显示缓冲区的大小=宽度×高度×4字节)。
像素点在显示缓冲区中按照从左到右、从上向下的顺序依次排列。
访问显示缓冲区请勿越界,否则会造成难以预料的后果。显示缓冲区中的每个点对应 RGBTRIPLE 类型的结构体:

struct RGBTRIPLE {
	BYTE rgbtBlue;
	BYTE rgbtGreen;
	BYTE rgbtRed;
}

RGBTRIPLE在内存中的表示形式为:0xrrggbb (bb=蓝,gg=绿,rr=红),而常用的COLORREF在内存中的表示形式为:0xbbggrr。注意两者的红色和蓝色是相反的,请用BGR宏交换红色和蓝色。
如果操作绘图窗口的显示缓冲区,请在操作完毕后,执行 FlushBatchDraw() 使操作生效。

//使用例子
#include <graphics.h>
#include <windows.h>
#include <cstdio>
int main()
{

	//初始化绘图窗口
	initgraph(640, 480, EX_SHOWCONSOLE);

	//获取指向显示缓冲区的指针
	DWORD* pMem = GetImageBuffer();//不写默认为NULL(表示默认的绘图窗口)

	//直接对显示缓冲区赋值
	for (int i = 0; i < 640 * 480; i++)
	{
		pMem[i] = BGR(RGB(0, 0, i * 256 / (640 * 480)));
		if (i % 1000 == 0)
		{
			Sleep(100);
		}
	}

	//使显示缓冲区生效(注:操作指向IMAGE的显示缓冲区不需要这条语句)
	FlushBatchDraw();
	//在计算机图形编程中,
	//我们经常需要将绘制的图形显示在屏幕上。
	//而绘制图形是一个相对耗费资源的操作,
	//如果每次绘制都立即显示在屏幕上,
	//会导致频繁的图形刷新,
	//可能会引起画面闪烁或者卡顿的问题。
	//为了提高绘制的效率和流畅度,
	//就引入了批量绘制的概念。
	//FlushBatchDraw()的作用是将之前批量绘制的图形一次性地刷新到屏幕上。
	//通俗地说,就好比是一个“提交”操作,
	//你之前进行的所有绘制都会在调用FlushBatchDraw()后一起显示在屏幕上

	//按任意键退出
	getchar();
	closegraph();

	return 0;
}

11.GetImageHDC:获取绘图设备句柄

这个函数以后再来补充……

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

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

相关文章

10--Gradle进阶 - Gradle任务的执行

10--Gradle进阶 - Gradle任务的执行 前言 在前面的篇章中&#xff0c;我们尝试执行了 gradle 的 task&#xff0c;但是不清楚有哪些语法&#xff0c;下面来介绍一下。 任务执行 任务执行语法&#xff1a;gradle [taskName...] [--option-name...]。 分类解释常见的任务&#xf…

沉浸式三维虚拟展厅交互体验科技感十足

随着科技的不断发展进步&#xff0c;展厅的表现形式也变得多样化&#xff0c;紧跟时代发展步伐&#xff0c;迭代创新。 3D虚拟展厅具有四大优势 一、降低成本&#xff0c;提高效率 3D“VR线上展厅”将艺术优势资源转到线上搭建的艺术线上展平台&#xff0c;相对传统艺术展来说有…

ModaHub魔搭社区:详解向量数据库Milvus的Mishards:集群分片中间件(二)

目录 元数据 服务发现 元数据 元数据记录了底层数据的组织结构信息。在分布式系统中&#xff0c;Milvus 写节点是元数据唯一的生产者&#xff0c;而 Mishards 节点、Milvus 写节点和读节点都是元数据的消费者。目前版本的 Milvus 只支持 MySQL 和 SQLite 作为元数据的存储后…

SpringBoot整合网易邮箱

SpringBoot整合邮箱 1&#xff0c;开启POP3/SMTP/IMAP服务 注意&#xff1a;每个邮箱的密码唯一&#xff0c;不要随意分享给他人 最后就是这个样子了 2&#xff0c;整合测试 2.1&#xff0c;pom.xml <?xml version"1.0" encoding"UTF-8"?> <…

Just KNIME it [S2C13] 机器学习的可解释性

朋友们&#xff0c;Just KNIME it 还有在跟进吗? 本季已经到 13 期啦。 本期探讨的主题是机器学习的可解释性问题&#xff0c;快随指北君一起看看吧。 挑战 挑战13&#xff1a;揭示犯罪率之迷 难度&#xff1a;中等 情境描述&#xff1a;作为一名在房地产公司任职的数据科学家…

Apikit 自学日记:发起文档测试-HTTP

HTTP 功能入口&#xff1a;API管理应用 / 选中某个项目 / API文档菜单 / 选中某一API文档 / 点击“测试”TAB API文档测试页&#xff0c;可对该API文档描述的接口进行快速测试。API文档测试页分为地址控制栏、请求控制区、返回展示区&#xff0c;以及测试辅助工具区共四个部分…

Android进阶之路 - 深入浅出字体、字体库

当时组内临时接到一个换字体库的需求&#xff0c;这个需求相对简单&#xff0c;因为手头有其他事情&#xff0c;同时之前也没换过字体库&#xff0c;就交给了同事去做了&#xff1b;现在有时间就好好充实下自己 ( 我写的也未必全对&#xff0c;如有不足可直接提出&#xff0c;相…

vue 组件基本使用方法

前言:vue 可以比较灵活的使用 html的片段&#xff0c;并将html的片段进行数据隔离&#xff0c;参数也可以互相传递&#xff0c;组件与组件之间也可以进行数据的交互 合理的使用组件可以避免重复代码或者很方便的调用第三方组件库 vue组件 简单实例组件传参实际应用父子组件交互…

右键文件夹添加指定打开的程序(如:IDEA、PyCharm等)

一.打开注册表 使用winR打开运行界面(默认为左下角)输入regedit 二.进入指定目录 1.找不到可直接复制路径: 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell 2.在当前路径shell下右键->新建->项->命名IDEA &#xff08;名字任意即可&#xff09;,修改默认…

利用影刀RPA批量导出excel中的图片并重命名

本程序要求excel中的图片应该符合以下截图中的格式&#xff1a; 图片和名称应该处于同一行&#xff0c;而且图片应该是嵌入在单元格中 程序参考&#xff1a;

linux系统Nginx服务Rewrite重写

文章目录 一、Rewrite跳转场景二、Rewrite跳转实现三、Rewrite实际场景1.Nginx跳转需求的实现方式2.rewrite放在 server{}、if{}、location{}段中3.对域名或参数字符串 四、Nginx正则表达式1.常用的正则表达式元字符2.正则表达式的优点 五、Rewrite命令1.Rewrite命令语法2.flag…

数字IC前端学习笔记:仲裁轮询(六)

相关文章 数字IC前端学习笔记&#xff1a;LSFR&#xff08;线性反馈移位寄存器&#xff09; 数字IC前端学习笔记&#xff1a;跨时钟域信号同步 数字IC前端学习笔记&#xff1a;信号同步和边沿检测 数字IC前端学习笔记&#xff1a;锁存器Latch的综合 数字IC前端学习笔记&am…

数据库学习3

主键使用 主键的使用 CREATE TABLE t17 (id INT PRIMARY KEY ,name VARCHAR(32), email VARCHAR(32)); 主键列的值不可以重复 INSERT INTO t17 VALUES(1,jack,jacksohu.com); INSERT INTO t17 VALUES(2,tom,tomsohu.com); INSERT INTO t17 VALUES(1,hsp,hspsohu.com); SELECT …

《计算机系统与网络安全》 第九章 访问控制技术

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

2022(二等奖)C859基于WebGIS的南京市排污口管理系统

作品介绍 一、需求分析 &#xff08;一&#xff09;社会需求 《国务院办公厅关于加强入河入海排污口监督管理工作的实施意见》明确提出&#xff0c;入河入海排污口(以下简称排污口&#xff09;是指直接或通过管道、沟、渠等排污通道向环境水体排放污水的口门&#xff0c;是流…

Day40

思维导图 练习 定义一个命名空间Myspace&#xff0c;包含以下函数&#xff1a;将一个字符串中的所有单词进行反转&#xff0c;并输出反转后的结果。例如&#xff0c;输入字符串为"Hello World"&#xff0c;输出结果为"olleH dlroW"&#xff0c;并在主函数…

Visual C++中的虚函数和纯虚函数的定义

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天来说说Visual C中的虚函数和纯虚函数。 直接说虚函数和纯虚函数有很多人会直接晕&#xff0c;但是来看这篇帖子的很多人是有JAVA或其他面象对象编程基础的&#xff0c;我要不就先作个类比&#xff0c;究…

【Java面试题】Java基础——排序算法

文章目录 冒泡排序★★★算法步骤动图演示代码示例 选择排序算法步骤动图演示 插入排序算法步骤动图演示 快速排序算法步骤动图演示 冒泡排序★★★ 冒泡排序&#xff08;Bubble Sort&#xff09;也是一种简单直观的排序算法。 它重复的遍历过要排序的数列&#xff0c;一次比…

Debian 12 “bookworm” 正式发布

经过 1 年 9 个月零 28 天的开发&#xff0c;Debian 项目推出了其新的稳定版本 12&#xff08;代号 bookworm&#xff09;。 Debian 12 包含超过 11,089 个新软件包&#xff0c;总计 64,419 个软件包&#xff0c; 6,296 个软件包已作为过时包删除。此版本更新了 43,254 个软件…

threejs让模型始终面向相机

需求&#xff1a;threejs导入3D模型&#xff0c;改变相机位置的同时&#xff0c;让模型始终面向相机。 实现方式&#xff1a;使用模型的lookAt()方法&#xff0c;设置模型lookAt的值 首次加载模型时&#xff0c;面向相机 load.load(/model5.glb, g > {// 获取相机位置const…