超全Python图像处理讲解(多图预警)

超全Python图像处理讲解(多图预警)文章目录Pillow模块讲解一、Image模块1.1、打开图片和显示图片1.2、创建一个简单的图像1.3、图像混合(1)透明度混合(2)遮罩混合1.4、图像缩放(1)按像素缩放(2)按尺寸缩放1.5、图像的剪切与粘贴(1)图像粘贴(2)裁剪图像1.4、图像旋转和格式转换(1)图像旋转(2)格式转换1.5、分离和合并(1)分离(2)合并二、ImageFilter2.1、高斯模糊2.2、其它滤镜三、…

大家好,又见面了,我是你们的朋友全栈君。

Pillow模块讲解

一、Image模块

1.1 、打开图片和显示图片

对图片的处理最基础的操作就是打开这张图片,我们可以使用Image模块中的open(fp, mode)方法,来打开图片。open方法接收两个参数,第一个是文件路径,第二个是模式。主要的模式如下:

mode(模式) bands(通道) 说明
“1” 1 数字1,表示黑白二值图片,每个像素用0或1共1位二进制码表示
“L” 1 灰度图
“P” 1 索引图
“RGB” 3 24位真彩图
“RGBA” 4 “RGB”+透明通道
“CMYK” 4 印刷模式图像

光理论是不够的,在此送大家一套2020最新Python全栈项目视频教程,点击此处 进来获取 跟着练习下,希望大家一起进步哦!
更多的模式也就不说了,关于模式的模式的详细介绍我也不知道。这个open方法返回一个Image对象,mode也不是必须参数。打开图片代码如下:

from PIL import Image
# 打开图片
im = Image.open('test.jpg')
# 显示图片
im.show()

当然显示图片不是我们的重点,我们获取Image对象之后,就可以获取它的一些信息了。

print('图像的格式:', im.format)
print('图像的大小:', im.size)
print('图像的宽度:', im.width)
print('图像的高度:', im.height)
# 传入坐标的元组
print('获取某个像素点的颜色值:', im.getpixel(100, 100))

在我的环境中运行结果如下:

图像的格式: JPEG
图像的大小: (3968, 2976)
图像的宽度: 3968
图像的高度: 2976
获取某个像素点的颜色值: (198, 180, 132)

1.2、创建一个简单的图像

在Image模块中,提供了创建图像的方法。主要是通过**Image.new(mode, size, color)**实现,该方法传入三个参数:

  • mode:图像的创建模式
  • size:图像的大小
  • color:图像的颜色

用该方法可以创建一个简单的图像,之后我们可以通过save方法将图像保存:

from PIL import Image
# 创建一个简单的图像
im = Image.new('RGB', (100, 100), 'red')
# 保存这个图像
im.save('red.png')

生成图片如下:

超全Python图像处理讲解(多图预警)

1.3、图像混合

(1)透明度混合

透明度混合主要是使用**Image中的blend(im1, im2, alpha)**方法,对该方法的解释如下:

  • im1:Image对象,在混合的过程中,透明度设置为(1-apha)
  • im2:Image对象,在混合的过程中,透明度设置为(apha)
  • alpha:透明度,取值是0-1。当透明度为0是,显示im1对象;当透明度为1时,显示im2对象

注意:im1和im2的大小必须一样,且mode都为RGB

代码实现如下:

from PIL import Image

# 打开im1
im1 = Image.open('pic.jpg').convert(mode='RGB')
# 创建一个和im1大小一样的图像
im2 = Image.new('RGB', im1.size, 'red')
# 混合图片,并显示
Image.blend(im1, im2, 0.5).show()

下面为原图和混合图的对比:

超全Python图像处理讲解(多图预警)

不得不说,我家艾斯真滴帅。

(2)遮罩混合

接下来就是很迷的时刻了,我们可以通过Image.composite(im1, im2, mask)方法实现遮罩混合。三个参数都是Image对象,该方法的作用就是使用mask来混合im1和im2。我是听不懂,你们能听懂最好给我讲一下。具体实现如下:

# 这句代码写了好多遍,我真不想写了
from PIL import Image
# 打开图像1
im1 = Image.open('pic1.jpg')
# 打开图像2
im2 = Image.open('pic2.jpg')
# 重新设置im2的大小
im2.resize(im1.size)
# 将图像2的三个色道分离,其中r、g、b都为Image对象
r, g, b = im2.split()
# 遮罩混合
Image.composite(im1, im2, b).show()

注意:im1、im2和mask的大小必须一样

im1、im2和遮罩混合效果对比如下:

超全Python图像处理讲解(多图预警)

依旧是我帅气的艾斯。

1.4、图像缩放

(1)按像素缩放

按像素缩放通过Image.eval(im1, fun)方法实现,其中im1为我们老生常谈的Image对象了;第二个为一个方法(函数),该函数传入一个参数,即像素点。该函数会对图片中每个像素点进行函数内的操作。下面我们对来简单使用一下这个方法:

from PIL import Image
# 打开一张图像
im = Image.open('抠鼻屎.jpg')
# 对该图像每个像素点进行*2处理
Image.eval(im, lambda x:x*2).show()

这里我使用的lambda表达式,当然一般也都是用lambda表达式,不过你也可以像下面这样写:

# 定义一个方法
def func(x):
    return x*2
# 对图像im每个像素点进行func中的操作,其中func不能加()
Image.eval(im, func)

效果图如下:

超全Python图像处理讲解(多图预警)

细心的读者应该可以发现,这个抠鼻屎的图片和笔者头像并不完全一样。在血色方面,笔者的头像确实要差几分。

注意:笔者在日常生活中可不是天天在大街上抠鼻屎的那种。

(2)按尺寸缩放

按尺寸缩放是通过Image对象的thumbnail()方法实现的,这里不同于前面直接通过Image调用方法,而是使用Image的具体实例im2调用thumbnail方法,从而对im2直接进行处理。具体代码如下:

from PIL import Image
# 打开图像
im1 = Image.open('xx.jpg')
# 复制图像
im2 = im1.copy()
# 将复制后的图像进行缩放,传入一个元组
im2.thumbnail((100, 100))
# 输出图像大小
print("im1的大小", im1.size)
print('im2的大小', im2.size)

这里缩放图像并不会对图像进行变形,即显示效果是一样的。这里就不放效果图了,输入结果如下:

im1的大小 (960, 960)
im2的大小 (100, 100)

1.5、图像的剪切与粘贴

(1)图像粘贴

粘贴的实现主要是通过Image对象的paste(im, box, mask)方法,其中im为Image对象;box为要粘贴到的区域;mask为遮罩(我也不知道啥是遮罩)。其中box的参数有三种形式:

  • (x1, y1):将im左上角对齐(x1,y1)点,其余部分粘贴,超出部分抛弃
  • (x1, x2, y1, y2):将im粘贴至此区域
  • None:此时im必须与源图像大小一致

(2)裁剪图像

裁剪主要通过Image对象的crop(box)方法实现,box同粘贴中一致。

接下来我们做一个小练习,想将图像某个区域剪切下来,然后粘贴到另一个图像上:

from PIL import Image
# 打开图像
im = Image.open('nnz.jpg')
# 复制两份
im1 = im.copy()
im2 = im.copy()
# 剪切图片
im_crop = im1.crop((200, 200, 400, 400))
# 粘贴图片
im2.paste(im_crop, (30, 30))
im2.show()

原图和效果图对比如下:

超全Python图像处理讲解(多图预警)

貌美如花的娜娜子。

1.4、图像旋转和格式转换

(1)图像旋转

图像旋转就非常简单了,简单的一句代码,通过Image对象调用rotate(),该方法返回被旋转图像的一个副本:

from PIL import Image
im = Image.open('nnz.jpg')
# 旋转90度然后显示
im.rotate(90).show()

顺时针逆时针就不要问我了。

(2)格式转换

  • convert:转换图像的模式
  • transpose:转换图像的格式

convert之前已经使用过了,这里就简单演示一下transpose的作用,transpose主要传入一些Image中的常量:

from PIL import Image
# 打开图像
im = Image.open('nnz.jpg')
# 这里我也不知道注释啥了,总之效果和rotate(90)效果一样
im.transpose(Image.ROTATE_90).show()

效果图我也就不放了,给大家列出一些可以传入的常量和该常量的作用:

常量 作用
Image.FILP_TOP_BOTTOM 上下翻转
Image.FILP_LEFT_RIGHT 左右翻转
Image.ROTATE_90 翻转90°
Image.ROTATE_180 翻转180°
Image.TRANSPOSE 颠倒

我也不知道这是哪门子的格式转换。

1.5、分离和合并

(1)分离

这个是之前使用过的,通过Image对象的split()方法,将图像的RGB三个通道分离,并返回三个Image对象:

from PIL import Image
# 打开图像
im = Image.open('nnz.jpg')
# 分离通道,返回3个Image对象
r, g, b = im.split()

三个通道的效果图如下:

超全Python图像处理讲解(多图预警)

(2)合并

合并是通过Image.merge(mode, bands)方法实现的,其中mode为模式,bands为通道列表,传入一个列表类型数据。下面我实现以下小新多年来的愿望:

from PIL import Image
# 打开小新.jpg和娜娜子.jpg
im1 = Image.open('娜娜子.jpg')
im2 = Image.open('小新.jpg')
# 让im2大小和im1一样
im2.resize(im1.size)
# 将两个图像分别分离
r1, g1, b1 = im1.split()
r2, g2, b2 = im2.split()
# 合并图像
im3 = Image.merge('RGB', [r1, g2, b1])
im3.show()

效果图如下,看到这么美的图片,小新一定会感谢我的:

超全Python图像处理讲解(多图预警)

到这里,我们就把Image模块的大致内容讲解完了,接下来我们来了解PIL中更丰富的功能。

二、ImageFilter

ImageFilter中提供了很多常用的滤镜功能,

2.1、高斯模糊

高斯模糊也叫高斯平滑,是啥我也不知道,反正听名字就是模糊。我们结合上面的内容完成一个小案例:

from PIL import Image, ImageFilter
# 打开图像
im1 = Image.open('iron_man.jpg')
# 创建一个im1两倍宽的图像
img = Image.new('RGB', (im1.width*2, im1.height), 'red')
# 高斯模糊处理
im2 = im1.filter(ImageFilter.GaussianBlur)
# 将im1粘贴到img上
img.paste(im1, (0, 0))
# 将im2(高斯模糊后的图像)粘贴到img上
img.paste(im2, (im1.width, 0))
img.show()

为了考虑小新的感受,下面不再用娜娜子作为素材。我选取了一张钢铁侠的图片,运行结果如下:

超全Python图像处理讲解(多图预警)

希望各位读者不要误会,他俩真没说你帅,他俩只说笔者一个人帅。

2.2、其它滤镜

除了高斯模糊,ImageFilter中还提供了许多其它滤镜:

滤镜值 滤镜名词
BLUR 模糊效果
CONTOUR 轮廓
DETAIL 细节
EDGE_ENHANCE 边缘增强
EDGE_ENHANCE_MORE 边缘增强plus
EMBOSS 浮雕效果
FIND_EDGES 寻找边缘
SMOOTH 平滑

笔者用一张美女图片,测试了上面几个滤镜的效果,发现9张图是看起来是完全一样的。虽然完全一样,但是笔者还是打算将这次测试的结果作为我慈善事业的一部分,分享给各位读者。

超全Python图像处理讲解(多图预警)

其中1为高斯模糊,2-9分别为表格中的8个滤镜。

三、ImageChops模块(图像合成)

ImageChops模块中,提供了很多图像合成的方法。这些方法是通过计算通道中像素值来实现的,不同的方法有不同的计算方式。

3.1、加法运算

加法运算通过**ImageChops.add(image1, image2, scale=1.0, offset=0)**方法实现,合成公式如下:

out = (im1 + im2)/scale + offset

我也看不懂,其中scale和offset是有默认值的。所以使用时我们可以省略参数,具体实现如下:

from PIL import Image, ImageChops
# 打开图像
im1 = Image.open('im1.jpg')
im2 = Image.open('im2.jpg')
# 合成图像并显示
im3 = ImageChops.add(im1, im2)
im3.show()

实验结果产不忍赌,效果图如下:

在这里插入图片描述

3.2、减法运算

加法运算通过**ImageChops.subtract(image1, image2, scale=1.0, offset=0)**方法实现,合成公式如下:

out = (im1 - im2)/scale + offset

其使用和add方法是一致的,代码如下:

from PIL import Image, ImageChops
# 打开图像
im1 = Image.open('xscn.jpg')
im2 = Image.open('xscn2.jpg')
# 合成图像并显示
im3 = ImageChops.subtract(im1, im2)
im3.show()

原本是不想放效果图的,但是运行后,发现效果图比较美,所以想和大家分享一下:

在这里插入图片描述

希望大家读到这篇博客的时候是独自一人的深夜。

3.3、其它函数

因为大多数函数的使用都比较简单,所以后续的函数也不单独拿出来讲了,具体功效可以看下列表:

函数名 参数 作用 计算公式
darker(变暗) (image1, image2) 对比两种图片的像素,取两种图片中对应像素的较小值。(去亮留暗) min(im1, im2)
lighter(变亮) 同上 对比两种图片的像素,取两种图片中对应像素的较大值。(去暗留亮) max(im1, im2)
invert(反色) (image) 将max(255)减去每个像素的值 max-image
multiply(叠加) (image1, image2) 两种图片互相叠加。如果和黑色叠加,将获得一张很色图片 im1*im2/max
screen(屏幕) 同上 先反色后叠加 max-((max-im1)*(max-im2)/max)
difference(比较) 同上 各个像素做减法,取绝对值。如果像素相同结果为黑色 abs(im1-im2)

演示代码如下:

from PIL import Image, ImageChops

# 打开图像
im1 = Image.open("im1.jpg")
im2 = Image.open("im2.jpg")

# 对图像进行各种操作
im3 = ImageChops.darker(im1, im2)
im3.save('darker.jpg')
im3 = ImageChops.lighter(im1, im2)
im3.save('lighter.jpg')
im3 = ImageChops.invert(im1)
im3.save('invert.jpg')
im3 = ImageChops.multiply(im1, im2)
im3.save('multiply.jpg')
im3 = ImageChops.screen(im1, im2)
im3.save('screen.jpg')
im3 = ImageChops.difference(im1, im2)
im3.save('difference.jpg')

其中,我选取的素材im1和im2都是上面使用到的那两张,效果图如下:

在这里插入图片描述

这样,我的女神就被我毁的体无完肤了。

四、ImageEnhance模块(色彩、亮度)

ImageEnhance提供了许多函数,用于调整图像的色彩、对比度、亮度、清晰度等。调整图像的步骤如下:

  1. 确定要调整的参数,获取特定的调整器
  2. 调用调整器的enhance方法,传入参数进行调整。

注意:所有调整器都实现同一个接口,该接口中包含一个方法enhance

其中enhance方法接收一个参数factor,factor是一个大于0的数。当factor为1时,返回原图,当factor小于1返回减弱图,大于1返回增强图。

各个获取色彩调整器的方法如下:

方法名称 方法作用
ImageEnhance.Color() 获取颜色调整器
ImageEnhance.Contrast() 获取对比度调整器
ImageEnhance.Brightness() 获取亮度调整器
ImageEnhance.Sharpness() 获取清晰度调整器

虽然是很想偷懒,不去做实验,但是想想还是做了如下实验,代码如下:

from PIL import Image, ImageEnhance
# 打开im1
im1 = Image.open("gtx.jpg")
# 获取颜色(各种)调整器
enhance_im1 = ImageEnhance.Color(im1)
#enhance_im1 = ImageEnhance.Contrast(im1)
#enhance_im1 = ImageEnhance.Brightness(im1)
#enhance_im1 = ImageEnhance.Sharpness(im1)
# 减弱颜色(以及其它属性)
im2 = enhance_im1.enhance(0.5)
# 增强颜色(以及其它属性)
im3 = enhance_im1.enhance(1.5)

# 获取原图大小
w, h = im1.size
# 创建一个原图大小3倍的图片
img = Image.new("RGB", (w*3, h))
# 将减弱的图片放在最左边
img.paste(im2, (0, 0))
# 将原图放在中间
img.paste(im1, (w, 0))
# 将增强后的图片放在最右边
img.paste(im3, (w*2, 0))
# 显示图片
img.show()

其中,我们只需要修改获取调整器的代码就可以了,获取其它调制器的代码我注释了。然后看看效果图:

在这里插入图片描述

这种不伤大雅的工作,让我唐尼叔做再适合不过了。

另外再讲一个调节亮度的函数,但是这个函数时Image中的函数point(),而不是ImageEnhance的。该函数传入一个参数,使用方法和Image.eval()类似,使用示例如下:

from PIL import Image
# 打开图像
im1 = Image.open('gtx.jpg')

# 变暗操作
im2 = im1.point(lambda x:x*0.5)
# 变量操作
im3 = im1.point(lambda x:x*1.5)
# 获取原图大小
w, h = im1.size
# 创建一个原图大小3倍的图片
img = Image.new("RGB", (w*3, h))
# 将减弱的图片放在最左边
img.paste(im2, (0, 0))
# 将原图放在中间
img.paste(im1, (w, 0))
# 将增强后的图片放在最右边
img.paste(im3, (w*2, 0))
# 显示图片
img.show()

效果图如下:

在这里插入图片描述

五、ImageDraw模块

该模块提供了许多绘制2D图像的功能,我们可以通过绘制获取一个全新的图像,也可以在原有的图像上进行绘制。在我们使用该模块进行绘制时,我们需要先获取ImageDraw.Draw对象,获取方式如下:

from PIL import ImageDraw
# 构造函数中,im为一个Image对象
drawer = ImageDraw.Draw(im)

我们获取ImageDraw.Draw对象后就可以进行相应的绘制了。

5.1、绘制简单形状

在绘制之前,我们先创建一个空白的图片:

from PIL import Image, ImageDraw

# 创建一个300*300的白色图片
im = Image.new("RGB", (300, 300), "white")
# 获取ImageDraw.Draw对象
drawer = ImageDraw.Draw(im)

后续的绘制都可以使用对象drawer绘制。

(1)绘制直线

""" xy:起点坐标和终点坐标(x1, y1, x2, y2) fill:填充色。"red"、"blue"... width:轮廓粗细 joint:连接方式,可以是曲线 """
line(xy, fill, width, joint)
# 绘制直线
drawer.line((50, 50, 150, 150), fill='green',width=2)

(2)绘制矩形

""" xy:左上角坐标和右下角坐标(x1, y1, x2, y2) fill:填充色。"red"、"blue"... outline:轮廓色。同上 width:轮廓粗细 """
rectangle(xy, fill, outline, width)
# 使用示例
drawer.rectangle((50, 50, 150, 150), fill='green', outline='red', width=3)

(3)绘制圆弧

""" xy:包含圆弧所在圆的矩形的左上角坐标和右下角坐标(x1, y1, x2, y2) start:起始角度 end:终止角度 fill:填充色。"red"、"blue"... width:轮廓粗细 """
arc(xy, start, end, fill, width)
# 使用示例
drawer.arc((50, 50, 150, 150), start=0, end=90, fill='green', width=3)

对于xy参数的解释如图所示:

在这里插入图片描述

(4)绘制椭圆

""" xy:包含椭圆(或圆)的矩形的左上角坐标和右下角坐标(x1, y1, x2, y2) fill:填充色。"red"、"blue"... outline:轮廓颜色 width:轮廓粗细 """
ellipse(xy, fill, outline, width)
# 使用示例
drawer.ellipse((50, 50, 150, 150),fill='green', outline='red', width=3)

(5)绘制弦


""" xy:弦所在椭圆的矩形的左上角坐标和右下角坐标(x1, y1, x2, y2) start:开始角度 end:终点角度 fill:填充色。"red"、"blue"... outline:轮廓颜色 width:轮廓粗细 """
chord(xy, start, end, fill, outline, width)
# 使用示例
drawer.chord((50, 50, 150, 150),start=0, end=90, fill='green', outline='red', width=3)

(6)绘制扇形


""" xy:扇形所在椭圆的矩形的左上角坐标和右下角坐标(x1, y1, x2, y2) start:开始角度 end:终点角度 fill:填充色。"red"、"blue"... outline:轮廓颜色 width:轮廓粗细 """
pieslice(xy, start, end, fill, outline, width)
# 使用示例
drawer.pieslice((50, 50, 150, 150),start=0, end=90, fill='green', outline='red', width=3)

(7)绘制多边形

""" xy:多边形各个点坐标的元组/列表(x1, y1, x2, y2) fill:填充色。"red"、"blue"... outline:轮廓颜色 """
pieslice(xy, fill, outline)
# 使用示例
drawer.polygon((50, 50, 150, 150, 150, 200, 200, 250, 50, 50), fill='green', outline='red')

(8)绘制点

""" xy:点的坐标 fill:填充色。"red"、"blue"... """
point(xy, fill)
# 使用示例
drawer.point((100, 100), fill='black')

除了上面这些简单图形外,我们还可以使用Draw绘制文字。

5.2、绘制文字

绘制文字和绘制图形是一样的:

""" xy:起点坐标 text:绘制的文本 fill:填充色。"red"、"blue"... ...其中绘制文字还有许多其它参数 """
text(xy, text, fill)
# 使用示例
drawer.text((100, 100), text='zack' fill='red')

当我们绘制中文时,上述代码会报错,因为默认编码是不支持中文的。我们可以在C:/Windows/Fonts目录下找到字体文件,我们选择一个支持中文的。我这里直接是将字体文件复制到项目底下来了,代码如下:

from PIL import Image, ImageDraw, ImageFont
# 创建一个图像用于绘制文字
im = Image.new("RGB", (300, 300), "white")
drawer = ImageDraw.Draw(im)
# 获取字体对象
imFont = ImageFont.truetype('simkai.ttf', 30)
# 绘制文字时设置字体
drawer.text((50, 100),text="啥",font=imFont,fill="red")
im.show()

最后送大家一套2020最新Pyhon项目实战视频教程,点击此处 进来获取 跟着练习下,希望大家一起进步哦!

我们使用了ImageFont.truetype()函数获取字体对象,在获取时我们可以设置字体大小。到此我们就了解了PIL的各种操作了,感兴趣的读者可以关注我的个人公众号:ZackSock。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/151375.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月20日 下午3:36
下一篇 2022年6月20日 下午3:36


相关推荐

  • 命令行快速跳转/编辑神器fasd

    命令行快速跳转/编辑神器fasd天下武功唯快不破 命令行虽然很多时候很快 但是 整体的 cd ls cd ls 也是让人心烦 之前使用了 autojump 可以通过关键字跳转到最频繁操作的目录中 快 今天介绍的 fasd 除了可以像 autojump 一样在目录中跳转 还可以通过关键字打开最频繁操作的文件 更快 安装 CentOS 的默认软件仓库中没有 fasd 需要添加 opensuse 的软件仓库才可以 cd etc yum repos d

    2026年3月19日
    1
  • Android中如何根据图片url路径来获取网络图片

    Android中如何根据图片url路径来获取网络图片原文地址:Android中如何根据图片url路径来获取网络图片1、根据图片的URL路径来获取网络图片,核心代码如下:publicstaticBitmapgetBitmap(Stringpath)throwsIOException{URLurl=newURL(path);HttpURLConnectionconn=(HttpURLConnection)url

    2026年2月14日
    4
  • linux卸载命令_linux卸载服务命令

    linux卸载命令_linux卸载服务命令linux上使用rpm安装的一些软件,该如何进行卸载呢?卸载步骤:1、先使用rpm-qa|grep软件包名称例如卸载mysql:rpm-qa|grepmysql2、使用rpm-e–nodeps文件包名称rpm-e–nodepsmysql-5.0.77-4.el5_6.6rpm-e–nodepslibdbi-dbd-mysql-0.8.1a-1.2.2rpm-e–nodepsmysql-5.0.77-4.el5_6.6rpm..

    2026年2月17日
    6
  • Fluentd 配置

    Fluentd 配置GitHub nbsp https github com fluent fluentd Doc nbsp http docs fluentd org articles config file Example nbsp https github com fluent fluentd tree master example 默认配置文件 etc td agent td agent confFluen

    2026年3月19日
    2
  • Git 常用命令总结

    Git 常用命令总结

    2021年10月22日
    46
  • java解析xml文档并保存到数据库

    java解析xml文档并保存到数据库java解析xml文档并保存到数据库:sadf说明:用xml文档简单写一份新闻如下:洛阳未来一周将持续高温天气中国气象局洛阳未来一周将持续高温天气,局部地区温度高达39度!请大家做好防范高温,谨防中暑!河南科技大学跻身世界顶尖大学中国教育网据权威机构综合测评之后,河南科技大学全世界排名超前,成功跻身世界顶尖大学!洛阳牡丹甲天下中国旅游网洛阳牡丹甲不是

    2022年5月29日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号