用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使用xlrd模块读写Excel文件的方法
May 06 Python
全面了解Python的getattr(),setattr(),delattr(),hasattr()
Jun 14 Python
python xlsxwriter库生成图表的应用示例
Mar 16 Python
图解Python变量与赋值
Apr 03 Python
Tensorflow使用tfrecord输入数据格式
Jun 19 Python
pandas求两个表格不相交的集合方法
Dec 08 Python
Python3.5面向对象与继承图文实例详解
Apr 24 Python
python numpy之np.random的随机数函数使用介绍
Oct 06 Python
python 生成器和迭代器的原理解析
Oct 12 Python
Python3 shutil(高级文件操作模块)实例用法总结
Feb 19 Python
tensorflow中tf.reduce_mean函数的使用
Apr 19 Python
python实现Thrift服务端的方法
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
一个捕获函数输出的函数
2007/02/14 PHP
php 购物车完整实现代码
2014/06/05 PHP
PHP间隔一段时间执行代码的方法
2014/12/02 PHP
Laravle eloquent 多对多模型关联实例详解
2017/11/22 PHP
node.js 一个简单的页面输出实现代码
2012/03/07 Javascript
JavaScript将页面表格导出为Excel的具体实现
2013/12/27 Javascript
使用js判断TextBox控件值改变然后出发事件
2014/03/07 Javascript
Js实现手机发送验证码时按钮延迟操作
2014/06/20 Javascript
jQuery中eq()方法用法实例
2015/01/05 Javascript
javascript中Math.random()使用详解
2015/04/15 Javascript
分享9点个人认为比较重要的javascript 编程技巧
2015/04/27 Javascript
javascript中Date对象的使用总结
2016/11/21 Javascript
js获取隐藏元素的宽高
2017/02/24 Javascript
ES6中Generator与异步操作实例分析
2017/03/31 Javascript
Angular 2父子组件数据传递之@Input和@Output详解 (上)
2017/07/05 Javascript
mui开发中获取单选按钮、复选框的值(实例讲解)
2017/07/24 Javascript
js使用原型对象(prototype)需要注意的地方
2017/08/28 Javascript
微信小程序 页面滑动事件的实例详解
2017/10/12 Javascript
Angular2实现组件交互的方法分析
2017/12/19 Javascript
Angular父组件调用子组件的方法
2018/04/02 Javascript
自己动手封装一个React Native多级联动
2018/09/19 Javascript
[02:27]DOTA2英雄基础教程 莱恩
2014/01/17 DOTA
[09:13]2014DOTA2国际邀请赛 中国区预选赛coser表演
2014/05/23 DOTA
[01:52]深扒TI7聊天轮盘语音出处7
2017/05/11 DOTA
高性能web服务器框架Tornado简单实现restful接口及开发实例
2014/07/16 Python
Python中输出ASCII大文字、艺术字、字符字小技巧
2015/04/28 Python
python ftplib模块使用代码实例
2019/12/31 Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
2020/03/08 Python
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
蒙蒂塞罗商店:Monticello Shop
2018/11/25 全球购物
在求职信中如何凸显个人优势
2013/10/30 职场文书
五年级英语教学反思
2014/01/31 职场文书
会展策划与管理专业求职信
2014/06/09 职场文书
《我爱祖国》演讲稿1000字
2014/09/26 职场文书
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python
分析SQL窗口函数之取值窗口函数
2022/04/21 Oracle