推广 热搜: csgo  vue  2023  angelababy  gps  信用卡  新车  htc  落地  控制 

来得瑟一下!用Python做一个缩放自如的圣诞老人

   2023-07-09 网络整理佚名2250
核心提示:正如刚才所说,中的一幅图其实是一个三维数组,其实也可以把它看作是二维数组,数组中的上面代码中的image是已经缩放完毕的圣诞老人图片,和分别是空白图片的高度和宽度,这个尺寸可以根据需求自行设置。缩放比例间隔越小、准备的图片素材越多,生成的动图也就越平滑。当然了,这种动图制作方法不仅限于圣诞老人,任何图片理论上都是可以的。

圣诞节又到了。 虽然我们中国人不提倡西方的节日,但是商人还是很喜欢西方的节日。 估计有兴趣的男生女生也会喜欢的。

今天的主题是教大家如何制作一个成长中的圣诞老人,就像西游里的神怪们一样可以随意改变大小,算是送给大家的小礼物吧,先来发个图吧!

别担心,盯着图片看5秒

主要思考点:

1

图像缩放

本文的大部分工作都是基于实现,图像缩放极其容易,但是这次我们要生成一组按比例缩放的图像,因此使用了 cv2. 方法可能与过去略有不同。 进进出出,先看函数原型:

cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

其中,src为原始图像,dsize为目标图像的大小。 当dsize为0时,我们可以通过fx和fy参数设置横轴和纵轴的缩放比例。 这可能有点抽象,我们举个例子来说明一下:

for i in range(1, 40, 1):
  img = cv2.resize(image, (0, 0), fx=i/30, fy=i/30)
  cv2.imwrite(str(i)+'.png', img)

运行上面的代码会生成39张不同比例的图片。 目标图片的大小由缩放比例fx和fy控制。 最小图片的边长是原图的1/30,最大图片的边长是原图。 1.3倍(下):

既然已经有了按比例缩放的图片,那我们是不是可以选择一个坐标原点,直接合成动画呢? 答案是否定的,因为传统的动画生成方法要求素材图像必须具有相同的尺寸(像素),下面我们将重点解决这个问题。

2

底图叠加

中将两张图片叠加的方式有很多种,但都存在缺陷——要么叠加的图片必须大小相同,要么很难控制叠加的图片的具体位置。 对此,小编采取的方法是在两幅图像之间进行“像素级”的替换。

1)。 生成底​​图

在要叠加的图像中,上层图像使用刚刚获得的一系列比例缩放图像,下层图像我们生成固定大小的空白图像。 需要注意的是,这里生成的空白图片必须大于最大的缩放图片。

生成空白底图分两步完成。 第一步,生成固定大小(纵轴和横轴的长度)的二维数组; 第二步是使用cv2。 执行色彩空间变换。 代码如下所示:

blank = np.ones((blankh, blankw), dtype=np.uint8) * 255
ret = cv2.cvtColor(blank, cv2.COLOR_GRAY2BGR)

其实上面代码中的ret本质上是一个三维数组,我们可以把它打印出来查看(下图),但是cv2显示的却是一张空白图片。 方法。 这涉及到一些比较底层的内容,好让大家理解,文章中不再重复。

2)。 像素更换

刚才说了,里面的一张图其实就是一个三维数组,也可以看成是一个二维数组。

每个元素都是一个[255, 255, 255]形式的列表,里面存储了图像每个像素点的颜色参数。也就是说,如果我们要实现一张图片叠加在另一张图片上的视觉效果,我们可以控制叠加图片的对应位置

用于替换分配的像素。 代码形式如下图所示,其中i和j分别是图片的纵坐标和横坐标。

ret[i, j, 0] = image[i, j, 0]
ret[i, j, 1] = image[i, j, 1]
ret[i, j, 2] = image[i, j, 2]

对于图片来说,坐标原点在左上角(如下图所示)。 另外,为了保证动画的最终效果,不能简单的根据坐标原点进行图片的叠加。 最好的方法是将叠加原点设置在基础图像下边缘的中心。


弄清楚原理后,就可以开始进行图像叠加操作了。 这期间需要计算一些像素对应的位置。 虽然有点绕,但其实并不复杂。 详细的换算公式就不写了。 我们直接看代码:

上面代码中的图像是经过缩放的圣诞老人图像,以及空白图像的高度和宽度。 这个尺寸可以根据自己的需要来设置。

下图是一张缩放比例约为1/2的图片与底图的叠加效果。 为了方便观察,我给图片加了边框。

3

生成动画

之前我们已经解决了单图与底图的叠加。 为了准备合成动画所需的素材,我们还需要对多张按比例缩放的图片进行底图叠加操作。 缩放间隔越小,准备的图像素材越多,生成的动画就越流畅。

当然,动画的效果必须综合考虑多种因素。 这里,小编依然用了39张图片来组合动画。 其中,最小图形高度为原图的1/30,最大图形高度为原图的1.3倍。 与底图叠加的图像如下所示。

我们来说说动画的合成。 使用该库可以实现将多张相同尺寸的图片组合成动画。 核心代码只有一段:

imageio.mimwrite('目标文件名称.gif', gifList, duration=0.15)

第一个参数是git目标文件的名称; 是一组要合成的图片,即上图所示的那些; 最后一个参数表示屏幕切换的时间间隔,单位为秒。

现在使用以下代码进行动画合成。

file_path = 'pic'
imgList = os.listdir(file_path)
imgList = ['pic/'+img for img in imgList]
gifList = [imageio.imread(img) for img in imgList]
imageio.mimwrite('gif.gif', gifList, duration=0.15)

我们来看看合成动画的效果(下图)。 仔细一看,似乎有些不对劲。 为什么图中的圣诞老人这么大又这么小? 这与我们的预期不同。

其实问题就出在合成图像的顺序上。 我们尝试打印上面代码中的变量,结果如下:

可以看到,素材图片并没有按照我们预期的顺序排序。 这也是文件处理中比较常见的问题。 解决方案之一是根据图片的创建时间对图片进行排序。 具体操作是在上面第二行代码后面插入一条语句:

imgList = sorted(imgList,key=lambda x: os.path.getmtime(os.path.join(file_path, x)))

现在再次进行动画合成,就可以达到文章开头的效果了。

当然,这种动画制作方法并不局限于圣诞老人,任何图片理论上都是可以的。 例如,我们还可以制作一棵不断生长的圣诞树!

观看下面的视频一睹为快!

趣味游戏文章:

技巧和窍门:

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON