用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使用PyV8执行javascript代码示例分享
Dec 04 Python
python实现各进制转换的总结大全
Jun 18 Python
Python操作csv文件实例详解
Jul 31 Python
python读取视频流提取视频帧的两种方法
Oct 22 Python
Python解决八皇后问题示例
Apr 22 Python
解决使用PyCharm时无法启动控制台的问题
Jan 19 Python
Python逐行读取文件中内容的简单方法
Feb 26 Python
python 哈希表实现简单python字典代码实例
Sep 27 Python
Pytorch Tensor基本数学运算详解
Dec 30 Python
Python 爬取必应壁纸的实例讲解
Feb 24 Python
python去除删除数据中\u0000\u0001等unicode字符串的代码
Mar 06 Python
Python运行异常管理解决方案
Mar 09 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中显示格式化的用户输入
2006/10/09 PHP
PHP初学者头疼问题总结
2006/10/09 PHP
一组PHP可逆加密解密算法实例代码
2014/01/21 PHP
yiic命令时提示“php.exe”不是内部或外部命令的解决方法
2014/12/18 PHP
Mootools 1.2教程 Fx.Morph、Fx选项和Fx事件
2009/09/15 Javascript
Javascript Math ceil()、floor()、round()三个函数的区别
2010/03/09 Javascript
JavaScript 学习初步 入门教程
2010/03/25 Javascript
JavaScript 常见安全漏洞和自动化检测技术
2015/08/21 Javascript
jQuery向父辈遍历的简单方法
2016/09/18 Javascript
Javascript计算二维数组重复值示例代码
2016/12/18 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
2017/01/12 Javascript
nodejs读写json文件的简单方法(必看)
2017/03/09 NodeJs
EasyUI Datebox 日期验证之开始日期小于结束时间
2017/05/19 Javascript
ReactNative踩坑之配置调试端口的解决方法
2017/07/28 Javascript
vue页面使用阿里oss上传功能的实例(一)
2017/08/09 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
2017/10/11 Javascript
vue做移动端适配最佳解决方案(亲测有效)
2018/09/04 Javascript
Vue axios全局拦截 get请求、post请求、配置请求的实例代码
2018/11/28 Javascript
Vue分页器实现原理详解
2019/06/28 Javascript
es6中reduce的基本使用方法
2019/09/10 Javascript
python实现简易数码时钟
2021/02/19 Python
Python使用paramiko操作linux的方法讲解
2019/02/25 Python
pycharm 更改创建文件默认路径的操作
2020/02/15 Python
Python发起请求提示UnicodeEncodeError错误代码解决方法
2020/04/21 Python
澳大利高级泳装品牌:Bondi Born
2018/05/23 全球购物
英国电视和家用电器购物网站:rlrdistribution.co.uk
2018/11/20 全球购物
英国性能汽车零件和发动机配件在线:Maxpeedingrods
2019/11/05 全球购物
德国、奥地利和瑞士最大的旅行和度假门户网站:HolidayCheck
2019/11/14 全球购物
HomeAway英国:全球领先的度假租赁在线市场
2020/02/03 全球购物
模具设计与制造专业应届生求职信
2013/10/18 职场文书
供货协议书
2014/04/22 职场文书
大学课外活动总结
2014/07/09 职场文书
房产分割协议书范文
2014/11/21 职场文书
中学生社会实践教育活动总结
2015/05/06 职场文书
重阳节座谈会主持词
2015/07/03 职场文书
留学文书中的个人陈述,应该注意哪些问题?
2019/08/23 职场文书