用Python制作音乐海报


Posted in Python onJanuary 26, 2021

前言

前段时间在一个朋友那么得到的灵感,想到可以用音乐播放页面作为一张海报图片。其实接下来要讲的和海报还是有差距的,而具体实现也只是简单的图片粘贴,但是在效果上还是不错的。效果图如下,希望大家喜欢:

用Python制作音乐海报

左边是原图,右边是需要添加到中间的图,也是图的主角。其实如果直接用ps实现上面的图是非常简单的,反倒是用代码实现有点曲折,不过实现过程还是非常有趣的,希望这篇博客可以可以让你学到知识。

用Pillow创建圆形图

在上面的图片中,中间是一个圆形图片,而Pillow本身是没有提供生成圆形图片的方法(也可能是我没找到),所以就需要自己实现。在实现之前,我们先安装Pillow模块:

pip install pillow

要创建圆形图,我们先根据原图的大小,创建一个RGBA模式的透明图:

# 该方法传入三个参数,第一个为模式,第二个为大小的元组,第三个为颜色
im = Image.new('RGBA', (300, 300), (255, 255, 255, 0))

上述代码是创建了一个完全透明的300*300的图片,我们在该图片上绘制一个最大的圆:

# 获取绘制者
drawer = ImageDraw.Draw(im)
# 绘制一个黄色的圆,ellipse方法传入三个参数,第一个为包含该圆的最小正方形的区域,第二个为颜色,第三个为边宽
drawer.ellipse((0, 0, 300, 300), fill=(255, 255, 0), width=0)

生成图片如下:

用Python制作音乐海报

我们准备一张300*300的正方形图片,然后遍历图片的每个像素,如果像素值的A==0(即像素不透明)那我们就将图片该区域的像素值设置为透明。

用Python制作音乐海报

代码如下:

# 打开要转换成圆形的图片,我们事先把图片裁剪好
pic = Image.open(img_path).convert('RGBA')
# 遍历图片的每个像素
for i in range(300):
  for j in range(300):
    # 获取该像素点的像素
     r, g, b, a = im.getpixel((i, j))
    # 当rgb值不是黄色时,即像素值为透明时
    if (r, g, b) != (255, 255, 0):
      # 将原图的像素值设置为透明
      pic.putpixel((i, j), (255, 255, 255, 0))

我们的pic就是圆形图片了,完整代码如下:

# 背景图中圆的直径
radius = 533
# 图片的大小
circle_size = (radius, radius)
def generate_circle_image(img_path):
  # 创建一个透明的正方形
  im = Image.new('RGBA', circle_size, (255, 255, 255, 0))
  # 获取绘画者
  drawer = ImageDraw.Draw(im)
  # 在透明的正方形上画一个黄色的圆
  drawer.ellipse((0, 0, circle_size[0], circle_size[1]), fill=(255, 255, 0), width=0)
  # 打开要转换成圆形的图片,我们事先把图片裁剪好
  pic = Image.open(img_path).convert('RGBA')
  # 修改图片大小,让图片和圆大小一样
  re_pic = pic.resize(circle_size, Image.ANTIALIAS)
  # 遍历图片的每个像素
  for i in range(circle_size[0]):
    for j in range(circle_size[1]):
      r, g, b, a = im.getpixel((i, j))
      if (r, g, b) != (255, 255, 0):
        re_pic.putpixel((i, j), (255, 255, 255, 0))
  return re_pic

在上面的方法中,我们改进了一些代码,之前我们需要使用指定大小的图片作为素材,现在只需要是正方形图片就可以了。

生成海报

原本我以为直接将圆形图片粘贴到背景图片上就可以了,但是试过之后发现效果和我想的不太一样,反正就是没成功,效果如下:

用Python制作音乐海报

是粘贴上去了没错,而且图片也是透明效果,但是从这个效果来看粘贴只是像素替换,而不是图片叠加。于是我又想到了遍历像素的办法。

我通过特殊手段获取了上面正方形离左边的像素,和离上边的像素(其实就是用ps看了一下)。我尝试过图形检测和像素判断的办法,想自动识别中间圆的位置,但是效果不佳(反正就是失败了),所以只能无耻的用ps查看像素。

回到正题,我们用遍历像素的办法不需要遍历整个图片,只需要从(left, top)像素开始,遍历到(left+radius, top+radius)区域即可,也就是遍历正方形区域(left、top和radius都是我通过ps获取的)。

我们先将背景图片拷贝一份,然后在副本上进行粘贴。然后遍历粘贴后的图片,如果像素值为透明,我们就将原图该位置的像素替换至副本处,实现原理和上面一样,代码如下:

def generate_music_post(circle_im, bg_im):
   """
     传入圆形图片和背景图片生成音乐海报
     circle_im:圆形图片
     bg_im:背景图片
     return:生成的图片
   """
  # 拷贝副本
  bg_copy = bg_im.copy()
  # 将圆形图片粘贴到副本上
  bg_copy.paste(circle_im, (left, top))
  # 遍历像素正方形区域
  for i in range(left, left+radius):
    for j in range(top, top+radius):
      # 获取像素值
      color = bg_copy.getpixel((i, j))
      # 如果像素透明。color的值为(r,g,b,a),color[3]为a的值,即透明值
      if color[3] == 0:
        # 将原图像素替换至副本透明处
        bg_copy.putpixel((i, j), bg_im.getpixel((i, j)))
  # 返回合成后的图片
  return bg_copy

这样就完成了。完整代码如下:

from PIL import Image, ImageDraw

left = 273      # 圆离左边的距离
top = 573      # 圆离上边的距离
radius = 533    # 圆的直径
circle_size = (radius, radius)    # 圆的外接正方形的大小

def generate_circle_image(img_path):
  # 创建一个透明的正方形
  im = Image.new('RGBA', circle_size, (255, 255, 255, 0))
  # 获取绘画者
  drawer = ImageDraw.Draw(im)
  # 在透明的正方形上画一个黄色的圆
  drawer.ellipse((0, 0, circle_size[0], circle_size[1]), fill=(255, 255, 0), width=0)
  # 打开要转换成圆形的图片,我们事先把图片裁剪好
  pic = Image.open(img_path).convert('RGBA')
  re_pic = pic.resize(circle_size, Image.ANTIALIAS)

  # 遍历图片的每个像素
  for i in range(circle_size[0]):
    for j in range(circle_size[1]):
      r, g, b, a = im.getpixel((i, j))
      if (r, g, b) != (255, 255, 0):
        re_pic.putpixel((i, j), (255, 255, 255, 0))

  return re_pic

def generate_music_post(circle_im, bg_im):
   """
     传入圆形图片和背景图片生成音乐海报
     circle_im:圆形图片
     bg_im:背景图片
     return:生成的图片
   """
  # 拷贝副本
  bg_copy = bg_im.copy()
  # 将圆形图片粘贴到副本上
  bg_copy.paste(circle_im, (left, top))
  # 遍历像素正方形区域
  for i in range(left, left+radius):
    for j in range(top, top+radius):
      # 获取像素值
      color = bg_copy.getpixel((i, j))
      # 如果像素透明。color的值为(r,g,b,a),color[3]为a的值,即透明值
      if color[3] == 0:
        # 将原图像素替换至副本透明处
        bg_copy.putpixel((i, j), bg_im.getpixel((i, j)))
  # 返回合成后的图片
  return bg_copy

# 生成圆形图片
pic = generate_circle_image('girl.jpeg')
# 以RGBA模式读取背景图片
bg_im = Image.open('music.jpg').convert('RGBA')
# 生成音乐海报
music_post = generate_music_post(pic, bg_im)
music_post.show()

另外,这个例子还可以更加智能。我们可以使用OpenCV识别主体图片的人脸,然后根据人脸区域计算一个比较适合的正方形区域,这样我们就不必传入正方形(不过还要考虑人脸识别的精确度等问题)。

代码已上传GitHub地址如下: https://github.com/IronSpiderMan/MusicPost

素材图片也在里面。

以上就是用Python制作音乐海报的详细内容,更多关于python 制作音乐海报的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
浅析Python中return和finally共同挖的坑
Aug 18 Python
Python探索之Metaclass初步了解
Oct 28 Python
python用户管理系统的实例讲解
Dec 23 Python
python获取酷狗音乐top500的下载地址 MP3格式
Apr 17 Python
详解django.contirb.auth-认证
Jul 16 Python
python对于requests的封装方法详解
Jan 03 Python
python爬虫-模拟微博登录功能
Sep 12 Python
django2.2安装错误最全的解决方案(小结)
Sep 24 Python
使用Bazel编译TensorBoard教程
Feb 15 Python
Python中格式化字符串的四种实现
May 26 Python
Django实现微信小程序支付的示例代码
Sep 03 Python
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 Python
python中pyqtgraph知识点总结
Jan 26 #Python
Appium+Python实现简单的自动化登录测试的实现
Jan 26 #Python
使用Python+Appuim 清理微信的方法
Jan 26 #Python
详解使用python爬取抖音app视频(appium可以操控手机)
Jan 26 #Python
python Matplotlib基础--如何添加文本和标注
Jan 26 #Python
python如何用matplotlib创建三维图表
Jan 26 #Python
python软件测试Jmeter性能测试JDBC Request(结合数据库)的使用详解
Jan 26 #Python
You might like
提高PHP编程效率的方法
2013/11/07 PHP
php建立Ftp连接的方法
2015/03/07 PHP
laravel 框架配置404等异常页面
2019/01/07 PHP
Thinkphp5框架简单实现钩子(Hook)行为的方法示例
2019/09/03 PHP
jquery实现的带缩略图的焦点图片切换(自动播放/响应鼠标动作)
2013/01/23 Javascript
如何用JavaScript动态呼叫函数(两种方式)
2013/05/03 Javascript
jQuery中get和post方法传值测试及注意事项
2014/08/08 Javascript
JavaScript计时器示例分析
2015/02/05 Javascript
jQuery 遍历函数详解
2015/07/05 Javascript
javascript实现网页背景烟花效果的方法
2015/08/06 Javascript
详解JavaScript的变量和数据类型
2015/11/27 Javascript
jQuery使用$.ajax进行即时验证的方法
2015/12/08 Javascript
jquery对复选框(checkbox)的操作汇总
2016/01/13 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
浅谈Vue.nextTick 的实现方法
2017/10/25 Javascript
AngularJS2 与 D3.js集成实现自定义可视化的方法
2017/12/01 Javascript
bootstrap3中container与container_fluid外层容器的区别讲解
2017/12/04 Javascript
vuejs项目打包之后的首屏加载优化及打包之后出现的问题
2018/04/01 Javascript
Koa代理Http请求的示例代码
2018/10/10 Javascript
vue生命周期的探索
2019/04/03 Javascript
微信小程序版本自动更新的方法
2019/06/14 Javascript
解决Vue watch里调用方法的坑
2020/11/07 Javascript
基于python脚本实现软件的注册功能(机器码+注册码机制)
2016/10/09 Python
Python操作MongoDB详解及实例
2017/05/18 Python
基于Python 装饰器装饰类中的方法实例
2018/04/21 Python
Python matplotlib 画图窗口显示到gui或者控制台的实例
2018/05/24 Python
python读取word 中指定位置的表格及表格数据
2019/10/23 Python
pandas中的数据去重处理的实现方法
2020/02/10 Python
如何用Python徒手写线性回归
2021/01/25 Python
罗技英国官方网站:Logitech UK
2020/11/03 全球购物
残疾人小组计划书
2014/04/27 职场文书
离婚协议书的书写要求
2014/09/17 职场文书
2014年老干部工作总结
2014/11/21 职场文书
论文答谢词
2015/01/20 职场文书
netty 实现tomcat的示例代码
2022/06/05 Servers
springboot集成redis存对象乱码的问题及解决
2022/06/16 Java/Android