Qt中2D绘制系统

目录

一、Qt绘制系统

1.1Qt绘制基本概念

1.2 绘制代码举例

1.3画家

1.3.1 QPainter的工作原理:

1.3.2 自定义绘制饼状图:

1.4画笔和画刷

1.4.1画笔

1.4.2 画刷填充样式

1.5 反走样和渐变

1.6绘制设备

1.7坐标变换

1.8QPainterPath

1.9绘制文字

1.10QMovie

二、图形视图框架的结构


一、Qt绘制系统

1.1Qt绘制基本概念

        Qt 的绘图系统允许使用相同的 API 在屏幕和打印设备上进行绘制。整个绘图系统基于 QPainter,QPainterDevice 和 QPaintEngine 三个类。

        QPainter 用来执行绘制的操作;QPaintDevice 是一个二维空间的抽象,这个二维空间可以由QPainter 在上面进行绘制;QPaintEngine 提供了画笔 painter 在不同的设备上进行绘制的统一的接口。QPaintEngine 类用在 QPainter 和 QPaintDevice 之间,并且通常对开发人员是透明的,除非你需要自定义一个设备,这时候你就必须重新定义 QPaintEngine 了

        Qt 的绘图系统实际上是说,使用 QPainter 使用画笔画刷等工具在 QPainterDevice 上面进行绘制,它们之间使用 QPaintEngine 引擎进行通讯。

1.2 绘制代码举例

        Qt 绘图系统提供了三个主要的参数设置,画笔(pen)、画刷(brush)和字体(font)。

//QPainter 接收一个 QPaintDevice*类型的参数。
//QPaintDevice 有很多子类,比如 QImage,以及QWidget。
//我们希望在这个 widget上画,因此传入的是 this 指针。
void QMyWidget::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	painter.drawLine(0, 0, 100, 50);
	painter.setPen(Qt::red);
	painter.drawRect(10, 10, 80, 40);
	painter.setPen(QPen(Qt::green, 5));
	painter.setBrush(Qt::blue);
	painter.drawEllipse(10, 10, 80, 40);


    //反走样 可以处理毛边效果 但是该算法复杂,不会默认开启,若要像素操作则不能开启这个
	painter.setRenderHint(QPainter::Antialiasing, true);
	//渐变是绘图中很常见的一种功能,可以把几种颜色混合在一起,自然地过渡,而不是一下子变成另一种颜色。
	//渐变一般是用在填充里面的,所以渐变的设置就是在 QBrush 里面。
	//Qt 提供了三种渐变画刷,分别是线性渐变(QLinearGradient)、辐射渐变(QRadialGradient)、角度渐变(QConicalGradient)。
	QLinearGradient linearGradient(10, 50, 90, 90);//起点xy 终点xy
	linearGradient.setColorAt(0.2, Qt::white);//渐变1/5处设置白色
	linearGradient.setColorAt(0.6, Qt::green);//3/5处设置绿色
	linearGradient.setColorAt(0.8, Qt::red);//4/5处设置绿色
	linearGradient.setColorAt(1.0, Qt::black);//终点设置黑色
	painter.setBrush(QBrush(linearGradient));
	painter.drawEllipse(10, 50, 80, 40);
	painter.setPen(QPen(QBrush(linearGradient), 10));//线条渐变
	painter.drawLine(10, 50, 90, 90);
	//角度渐变
	//QPainter的画刷、画笔、填充、渐变、坐标等属性记录在状态机中
	//当前改动后便会使用当前属性 改变画刷,坐标后只影响改动后
	int r = 60;
	QConicalGradient conicalGradient(0, 0, 0);//角度渐变的起始点 0,0 起始角度 0
	conicalGradient.setColorAt(0.0, Qt::red); 
	conicalGradient.setColorAt(60.0 / 360.0, Qt::yellow); 
	conicalGradient.setColorAt(120.0 / 360.0, Qt::green); 
	conicalGradient.setColorAt(180.0 / 360.0, Qt::cyan); 
	conicalGradient.setColorAt(240.0 / 360.0, Qt::blue); 
	conicalGradient.setColorAt(300.0 / 360.0, Qt::magenta); 
	conicalGradient.setColorAt(1.0, Qt::red);//角度回到起始 red
	painter.setBrush(QBrush(conicalGradient));
	painter.setPen(QPen(QBrush(conicalGradient),5));
	painter.translate(90+r, r+10);//修改坐标原点00到r,r
	painter.drawEllipse(QPoint(0, 0),r, r);
	//修改坐标 状态机恢复
	painter.fillRect(10, 10, 50, 100, Qt::red); 
	painter.save(); //保持当前状态
	painter.translate(100, 0); // 向右平移 100px 
	painter.fillRect(10, 10, 50, 100, Qt::yellow); 
	painter.restore();//绘制完之后在恢复之前状态
	painter.save(); 
	painter.translate(300, 0); // 向右平移 300px 
	painter.rotate(30); // 顺时针旋转 30 度 
	painter.fillRect(10, 10, 50, 100, Qt::green); 
	painter.restore();
	painter.save();
	painter.translate(400, 0); // 向右平移 400px 
	painter.scale(2, 3); // 横坐标单位放大 2 倍,纵坐标放大 3 倍 
	painter.fillRect(10, 10, 50, 100, Qt::blue); 
	painter.restore(); 
	painter.save();
	painter.translate(600, 0); // 向右平移 600px 
	painter.shear(0, 1); // 横向不变,纵向扭曲 1 倍 
	painter.fillRect(10, 10, 50, 100, Qt::cyan); 
	painter.restore();

	//不同的绘图设备
	//绘图设备是指继承 QPainterDevice 的子类。Qt 一共提供了四个这样的类,分别是 QPixmap、QBitmap、QImage 和 QPicture。
}

1.3画家

1.3.1 QPainter的工作原理:

        当你调用QPainter的绘图函数(例如drawRect()或drawText())时,实际上是向一个命令队列添加了一个命令。这个命令队列会在稍后被处理,并将结果绘制到目标设备(例如QPixmap或QWidget)。绘图命令被压入命令队列时,不会立即绘制到屏幕,而是会在事件循环的下一次迭代中被处理。这意味着你可以在一个函数中调用多次绘图命令,而不必担心每次调用都会导致屏幕刷新。

1.3.2 自定义绘制饼状图:

bool PmsPie::eventFilter(QObject *watcher, QEvent *event)
{
	if (event && ui.page_1->isVisibleTo(this)
		&& ui.page_1 == watcher
		&& event->type() == QEvent::Paint) {
		QPainter painter(ui.page_1);

		painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing, true);

		shared_ptr<int>pHelper(new int(0),
			[&](int *data) {
			delete data;
			painter.restore();//恢复画笔最初状态
		});
		painter.save();//保存画笔最初状态

		auto rect = ui.page_1->rect();
		painter.fillRect(rect, Qt::white);
		//*2 绘制内切弧线一般越界不显示 最大180
		int circle_diameter = qMin(rect.width(), rect.height() * 2);
		QRect rect_circle(8, 8, circle_diameter - 8, circle_diameter - 8);

		painter.setPen(Qt::NoPen);//设置NoPen
		const int bg_height = 2;//两条弧线之间的宽度 刻度尺宽度
		const int bg_span_angle = 180 * 16;//弧度转化16 从右边逆时针
		painter.setBrush(QColor("#f5f5f5"));
		//drawPie(外切rect adjusted调整大小后返回调整后的 adjust调整自身)
		painter.drawPie(rect_circle, 0, bg_span_angle);//0-180度的饼图作为刻度
		painter.setBrush(Qt::white);//adjust实际效果和调整对角坐标一样

		painter.drawPie(rect_circle.adjusted(bg_height, bg_height, -bg_height, -bg_height), 0, bg_span_angle);

		const int dp_height = 6;
		int percent = 70;
		int offset = dp_height - bg_height;
		int start_angle = 180 * (100 - percent) / 100 * 16;
		int span_angle = 180 * percent / 100 * 16; //30%

		painter.setBrush(Qt::green);
		painter.drawPie(rect_circle.adjusted(-offset, -offset, offset, offset), start_angle, span_angle);

		painter.setBrush(Qt::white);
		painter.drawPie(rect_circle.adjusted(offset, offset, -offset, -offset), 0, 360 * 16);

		//绘制文字
		QString str = QString("提升%1%").arg(30);
		const int text_offset = 8;
		auto font = painter.font();
		font.setBold(true);
		font.setPixelSize(circle_diameter * 0.086);
		painter.setPen(QPen(Qt::red, 8));
		painter.setFont(font);
		QRect rectText = QRect(rect_circle.left(), rect_circle.top(), rect_circle.width(), rect_circle.height() / 2);
		painter.drawText(rectText.adjusted(text_offset, text_offset, -text_offset, -text_offset), Qt::AlignHCenter | Qt::AlignBottom, str);
		//参考矩形绘制文本 可指定在矩形的位置
	}
	return QWidget::eventFilter(watcher, event);
}

1.4画笔和画刷

1.4.1画笔

风格种类 Qt::PenStyle

如果需要对绘制的线条设置不同的颜色,那么我们就需要给painter设置一个画笔QPen。Pen有样式(style),宽度(width), 颜色(brush), 笔帽样式(capStyle)和(连接样式)joinStyle

  • style使用Qt::PenStyle定义线条类型。默认是Qt::PenStyle::SolidLine

  • brush用于填充画笔笔生成的笔触。 使用QBrush类来指定画笔的颜色。

  • capStyle帽样式决定了可以使用QPainter绘制的线结束帽,

  • joinStyle连接样式描述了如何绘制两条线之间的连接。

通过使用相应的setStyle(),settwidth (), setBrush(), setCapStyle()和setJoinStyle()函数,可以很容易地修改各种设置(注意,当改变画笔的属性时,画家的画笔必须重置)。注意,不存在宽度为 0 的线。假设你设置 width 为 0,QPainter依然会绘制出一条线,而这个线的宽度为 1 像素。也就是说,画笔宽度通常至少是 1 像素。

笔帽样式:

连接样式:

1.4.2 画刷填充样式

        QBrush定义了QPainter的填充模式,具有样式、颜色、渐变以及纹理等属性;

样式:画刷的style()定义了填充的样式,使用Qt::BrushStyle枚举,默认值是Qt::NoBrush,也就是不进行任何填充。我们可以从下面的图示中看到各种填充样式的区别。

颜色:画刷的color()定义了填充模式的颜色,这个颜色可以是 Qt 预定义的颜色常量,也就是Qt::GlobalColor,也可以是任意QColor对象。

画刷的gradient()定义了渐变填充:这个属性只有在样式是Qt::LinearGradientPattern、Qt::RadialGradientPattern或者Qt::ConicalGradientPattern之一时才有效。渐变可以由QGradient对象表示。Qt 提供了三种渐变:QLinearGradient、QConicalGradient和QRadialGradient,它们都是QGradient的子类。

1.5 反走样和渐变

painter.setRenderHint(QPainter::Antialiasing, true);

        我们在光栅图形显示器上绘制非水平、非垂直的直线或多边形边界时,或多或少会呈现锯齿状外观。这是因为直线和多边形的边界是连续的,而光栅则是由离散的点组成。在光栅显示设备上表现直线、多边形等,必须在离散位置采样。由于采样不充分重建后造成的信息失真,就叫走样;用于减少或消除这种效果的技术,就称为反走样。反走样是图形学中的重要概念,用以防止通常所说的“锯齿”现象的出现。很多系统的绘图 API 里面都内置了有关反走样的算法,不过由于性能问题,默认一般是关闭的,Qt 也不例外。

        虽然反走样图像质量更好,但是由于反走样算法会使得局部像素比较模糊,因为需要以一种近似色代替原像素,这样看起来会模糊而圆滑,对于一些显示要求不高或者必须进行像素级操作的应用,不可反走样。

渐变:渐变是绘图中很常见的一种功能,简单来说就是可以把几种颜色混合在一起,让它们能够自然地过渡,而不是一下子变成另一种颜色;渐变一般是用在填充里面的,所以,设置渐变是在QBrush里面gradient()

1.6绘制设备

        QPixmap专门为图像在屏幕上的显示做了优化;QBitmap是QPixmap的一个子类,它的色深限定为1,你可以使用QPixmap的isQBitmap()函数来确定这个QPixmap是不是一个QBitmap。QImage专门为图像的像素级访问做了优化。QPicture则可以记录和重现QPainter的各条命令

QPixmap继承了QPaintDevice:因此,你可以使用QPainter直接在上面绘制图形。QPixmap也可以接受一个字符串作为一个文件的路径来显示这个文件,比如你想在程序之中打开 png、jpeg 之类的文件,就可以使用QPixmap。QPixmap是针对屏幕进行特殊优化的,它与实际的底层显示设备息息相关。注意,这里说的显示设备并不是硬件,而是操作系统提供的原生的绘图引擎。所以,在不同的操作系统平台下,QPixmap的显示可能会有所差别。在使用QPixmap时,你可以直接使用传值的形式,不需要传指针因为QPixmap提供了“隐式数据共享”。简单来说,就是一般对于大型数据(图像无疑就是这种“大型数据”),为性能起见,通常会采用传指针的方式,但是由于QPixmap内置了隐式数据共享,所以只要知道传递QPixmap。

QBitmap继承自QPixmap因此具有QPixmap的所有特性。不同之处在于,QBitmap的色深始终为 1,即一位二进制表现颜色(非黑即白)。所以说,QBitmap实际上是只有黑白两色的图像数据。由于QBitmap色深小,因此只占用很少的存储空间,所以适合做光标文件和笔刷。

QImage与QPixmap相比:最大的优势在于能够进行像素级别的操作。可以把QImage想象成一个 RGB 颜色的二维数组,记录了每一像素的颜色。

QImage绘制二维码代码:

        qrencode则是一款由C语言(完全兼容C++)写成的一个QR码生成与解码的函数库.它以GNU LGPL协议发布。

void Qmultiwidgettest::InitialQRCode()
{
	QRcode *qrcode = NULL;
	qrcode = QRcode_encodeString("https://www.baidu.com", 2, QR_ECLEVEL_Q, QR_MODE_8, 1);
	if (NULL == qrcode)
	{
		return;
	}

	const size_t scale = 4;

	qint32 qrcodeWidth = qrcode->width > 0 ? qrcode->width : 1;
	qrcodeWidth = scale * qrcodeWidth;
	QImage image = QImage(qrcodeWidth, qrcodeWidth, QImage::Format_ARGB32);//The image is stored using a 32-bit ARGB format (0xAARRGGBB).Alpha 透明度
	QPainter painter(&image);
	QColor background(Qt::white);
	painter.setBrush(background);
	painter.setPen(Qt::NoPen);
	painter.drawRect(0, 0, qrcodeWidth, qrcodeWidth);
	QColor foreground(Qt::black);
	painter.setBrush(foreground);

	for (qint32 y = 0; y < qrcode->width; y++)
	{
		for (qint32 x = 0; x < qrcode->width; x++)
		{
			unsigned char b = qrcode->data[y * qrcode->width + x];
			if (b & 0x01)
			{
				QRectF r(scale*x, scale*y, scale, scale);
				painter.drawRects(&r, 1);
			}
		}
	}
	/*if (!image.save("qrcode.png")) //保存到本地
	{
	}*/
	//ui.label_8->setPixmap(QPixmap::fromImage(image));
	ui.label_8->setPixmap(QBitmap::fromImage(image));//QBitmap继承QPixmap 色深为1
	QRcode_free(qrcode);
}

1.7坐标变换

        图形学大部分算法依赖于矩阵计算,坐标变换便是其中的代表:每一种变换都对应着一个矩阵乘法。 QTransform 用于指定坐标系的 2D 转换 - 平移、缩放、扭曲(剪切)、旋转或投影坐标系。绘制图形时,通常会使用。QTransform 与 QMatrix 不同之处在于,它是一个真正的 3x3 矩阵,允许视角转换,QTransform 的 toAffine() 方法允许将 QTransform 转换到 QMatrix。如果视角转换已在矩阵指定,则转换将导致数据丢失。

        A QTransform object contains a 3 x 3 matrix. The m31 (dx) and m32 (dy) elements specify horizontal and vertical translation. The m11 and m22 elements specify horizontal and vertical scaling. The m21 and m12 elements specify horizontal and vertical shearing. And finally, the m13 and m23 elements specify horizontal and vertical projection, with m33 as an additional projection factor.

 x' = m11*x + m21*y + dx
  y' = m22*y + m12*x + dy
  if (is not affine) {
      w' = m13*x + m23*y + m33
      x' /= w'
      y' /= w'
  }

1.8QPainterPath

        QPainter是一个状态机。那么,有时我想保存下当前的状态:当我临时绘制某些图像时,就可能想这么做。当然,我们有最原始的办法:将可能改变的状态,比如画笔颜色、粗细等,在临时绘制结束之后再全部恢复。对此,QPainter提供了内置的函数:save()和restore()。save()就是保存下当前状态;restore()则恢复上一次保存的结果。这两个函数必须成对出现:QPainter使用栈来保存数据,每一次save(),将当前状态压入栈顶,restore()则弹出栈顶进行恢复。

        而QPainterPath 提供了一个容器用于存储绘图操作以便可以创建和复用绘图,相较于QPainter每次状态保存和恢复更便利。

1.9绘制文字

        除了绘制图形以外,还可以使QPainter::darwText()函数来绘制文字,也可以使用QPainter::setFont()设置文字所使用的字体,使用QPainter::fontInfo()函数可以获取字体的信息,它返回QFontInfo类对象。在绘制文字时会默认使用抗锯齿。

        //绘制文字
		QString str = QString("提升%1%").arg(30);
		const int text_offset = 8;
		auto font = painter.font();
		font.setBold(true);
		font.setPixelSize(circle_diameter * 0.086);
		painter.setPen(QPen(Qt::red, 8));
		painter.setFont(font);
		QRect rectText = QRect(rect_circle.left(), rect_circle.top(), rect_circle.width(), rect_circle.height() / 2);
		painter.drawText(rectText.adjusted(text_offset, text_offset, -text_offset, -text_offset), Qt::AlignHCenter | Qt::AlignBottom, str);
		//参考矩形绘制文本 可指定在矩形的位置

1.10QMovie

QMovie类用于显示没有声音的简单动画。在实际运用中,可以用来显示Gif格式的动画 。

{
		auto movie = new QMovie(tr(":/ToolIcon/工具栏/a589d01596db63a93d83e0bfcfcc1008.gif"));
		int totalFrames = movie->frameCount();//总帧数
		QPixmap frame = movie->currentPixmap();//当前帧返回为PixMap对象
		QImage frameImage = movie->currentImage();
		//设置gif的加载方式,默认不会缓存所有帧 只有缓存后才可以跳帧jumpToFrame()、控制速度setSpeed()
		movie->setCacheMode(QMovie::CacheAll);
		movie->setScaledSize(ui.label_gif->size());//设置动画大小
		connect(movie, &QMovie::stateChanged, [=]() {
			QString str;
			switch (movie->state())
			{
			case QMovie::Paused:
				str = "Paused"; break;//播放暂停 可以重新start
			case QMovie::Running:
				str = "Running"; break;//初始未播放 或者播放完 并且不会播放任何内容
			case QMovie::NotRunning:
				str = "NotRunning"; break;
			}
			qDebug() << str;
		});
		ui.label_gif->setMovie(movie);
		movie->start();
		if (movie->state() == QMovie::Running)
		{
			movie->setSpeed(200);//200%速度播放
		}
	}

二、图形视图框架的结构

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于.NET调用WebService服务

基于.NET调用WebService服务 上一篇文章用java的Spring Boot框架搭建了一个WebService服务端&#xff0c;这篇文章通过.NET进行调用&#xff0c;下文基于Visual Studio 2022 引入WebService服务 项目右键 -> 添加 -> 服务引用 选择WCF Web Service&#xff0c;点击下一…

IIC 随机写+多次写 可以控制写几次

verilog module icc_tx#(parameter SIZE 2 , //用来控制写多少次 比如地址是0000 一个地址只能存放8bit数据 超出指针就会到下一个地址0001parameter CLK_DIV 50_000_000 ,parameter SPEED 100_000 ,parameter LED 50 )( input wire c…

微信小程序+Vant-自定义选择器组件(多选

实现效果 无筛选&#xff0c;如有需要可参照单选组件中的方法.json文件配置"component": true,columns需要处理成含dictLabel和dictValue字段&#xff0c;我是这样处理的&#xff1a; let list arr.map(r > {return {...r,dictValue: r.xxxId,dictLabel: r.xxx…

基于边缘智能网关的机房安全监测应用

随着我国工业互联网的扎实推进&#xff0c;越来越多地区积极建设信息基础设施&#xff0c;以充沛算力支撑产业物联网的可持续发展&#xff0c;数据机房就是其中的典型代表。而且随着机房规模的扩大&#xff0c;对于机房的安全管理难题挑战也日益增加。 面向数据机房安全监测与管…

HarmonyOS 应用跨团队 Debug 协作

文章目录 前言案例背景与问题分析问题背景问题分析工具 方法与代码实现前端模块的优化&#xff1a;日志记录与网络监听日志记录代码示例代码解析实现逻辑实际应用场景 网络状态监听代码示例代码解析实现逻辑实际应用场景 后端模块的优化&#xff1a;接口性能与容错机制接口性能…

《UnityShader 入门精要》更复杂的光照

代码&示例图见&#xff1a;zaizai77/Shader-Learn: 实现一些书里讲到的shader 到了这里就开启了书里的中级篇&#xff0c;之后会讲解 Unity 中的渲染路径&#xff0c;如何计算光照衰减和阴影&#xff0c;如何使用高级纹理和动画等一系列进阶内容 Unity 中的渲染路径 在U…

Ubuntu20.04安装kalibr

文章目录 环境配置安装wxPython下载编译测试报错1问题描述问题分析问题解决 参考 环境配置 Ubuntu20.04&#xff0c;python3.8.10&#xff0c;boost自带的1.71 sudo apt update sudo apt-get install python3-setuptools python3-rosinstall ipython3 libeigen3-dev libboost…

P1198 [JSOI2008] 最大数

P1198 [JSOI2008] 最大数https://www.luogu.com.cn/problem/P1198 牵制芝士&#xff1a;单调队列 思路&#xff1a; 我们的任务是找出一个区间最大值的 因为插入的数与上一次的答案有关 所以它是强制在线的&#xff08;真无语了&#xff09; 我们可以在每次插入时整一个叫…

宠物电商对接美团闪购:实现快速配送与用户增值

随着宠物行业的快速发展&#xff0c;宠物电商市场也在不断扩张。消费者的需求不再局限于传统的线上购物模式&#xff0c;越来越多的人开始追求更快捷的配送服务和更优质的购物体验。为了适应这一趋势&#xff0c;许多宠物电商平台开始寻求与本地配送平台合作&#xff0c;以提供…

阿里云oss转发上线-实现不出网钓鱼

本地实现阿里云oss转发上线&#xff0c;全部代码在文末&#xff0c;代码存在冗余 实战环境 被钓鱼机器不出网只可访问内部网络包含集团oss 实战思路 若将我们的shellcode文件上传到集团oss上仍无法上线&#xff0c;那么就利用oss做中转使用本地转发进行上线&#xff0c;先发送…

新型大语言模型的预训练与后训练范式,阿里Qwen

前言&#xff1a;大型语言模型&#xff08;LLMs&#xff09;的发展历程可以说是非常长&#xff0c;从早期的GPT模型一路走到了今天这些复杂的、公开权重的大型语言模型。最初&#xff0c;LLM的训练过程只关注预训练&#xff0c;但后来逐步扩展到了包括预训练和后训练在内的完整…

C#结构体排序(数组)

结构体排序&#xff08;数组&#xff09; 1 示例1.1 以PointF为例展示效果1.2 运行结果展示 2实际运用2.1 创建结构体2.2 调用示例2.3 运行结果展示 1 示例 1.1 以PointF为例展示效果 private void button1_Click(object sender, EventArgs e) {Random random new Random();…

前端高频面试题-并发请求

面试题中&#xff0c;有一道题经常会出现&#xff0c;咱们下面讲一下思路以及写法写一个方法&#xff0c;传入一个请求地址数组&#xff0c;以及一个并发数量&#xff0c;根据并发数量&#xff0c;一起发送请求。如果一个发送完&#xff0c;那么从数组中拿出来一个接着发送&…

RabbitMQ7:消息转换器

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

螺旋矩阵(java)

题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 代码思路&#xff1a; class Solution {public List<Integer> spiralOrder(int[][] matrix) {List<Integer> list new ArrayList<>(); …

Jenkins的使用

文章目录 一、Jenkins是什么\有什么用\与GitLab的对比二、Jenkins的安装与配置Jenkins的安装方式在Linux上安装Jenkins&#xff1a;在Windows上安装Jenkins&#xff1a;配置Jenkins&#xff1a; &#xff08;可选&#xff09;配置启动用户为root&#xff08;一定要是root吗??…

[在线实验]-ActiveMQ Docker镜像的下载与部署

镜像下载 下载ActiveMQ的Docker镜像文件。通常&#xff0c;这些文件会以.tar格式提供&#xff0c;例如activemq.tar。 docker的activemq镜像资源-CSDN文库 加载镜像 下载完成后&#xff0c;您可以使用以下命令将镜像文件加载到Docker中&#xff1a; docker load --input a…

【AI绘画】Midjourney进阶:色调详解(下)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;Midjourney中的色彩控制为什么要控制色彩&#xff1f;为什么要在Midjourney中控制色彩&#xff1f; &#x1f4af;色调纯色调灰色调暗色调 &#x1f4af…

YOLO系列论文综述(从YOLOv1到YOLOv11)【第3篇:YOLOv1——YOLO的开山之作】

YOLOv1 1 摘要2 YOLO: You Only Look Once2.1 如何工作2.2 网络架构2.3 训练2.4 优缺点 YOLO系列博文&#xff1a; 【第1篇&#xff1a;概述物体检测算法发展史、YOLO应用领域、评价指标和NMS】【第2篇&#xff1a;YOLO系列论文、代码和主要优缺点汇总】 ——————————…

数字图像处理(9):VGA接口及其时序

&#xff08;1&#xff09;特点&#xff1a;成本低、结构简单、应用灵活 VGA接口需要五个信号&#xff1a;R、G、B、Hsync、Vsync &#xff08;2&#xff09;VGA的工作原理&#xff1a; 设定一个高速时钟信号&#xff08;像素时钟&#xff09;来控制每个像素的传输速率&#…