这是我第一个正经的python程序,之前的无非是照抄廖大佬的教程胡乱试探的小程序。在敲这个程序之前,用了一个周末熟悉python的语法,廖雪峰老师的教程真的很棒!
在敲这个程序之前,我遇到许多烦心的小问题,在这里写下来也许对您有些帮助
0.设置模块路径
因为我用的是mac,自带了python,在敲这个程序之前用的都是python2.x,然而,当我想用python3.7编写程序时,却出了问题
首先是PIL库,我当时一句pip install pillow以为就能解决问题,在编译的时候pycharm却总是告诉我找不到pillow模块(我当时写的是from pillow import Image, ImageFont, ImageDraw )
后来发现,应该是
from PIL import Image, ImageFont, ImageDraw
然而,还是不行,它继续报错,PIL模块也找不到,接下来我就开始了漫长的浏览各种博客,发现我犯的错误真是不止一个
首先,pillow用不了是因为我是后装的python3.7,通过pip下载的pillow不在它默认的模块文件夹里
于是我先是这样:
>>>import sys
>>>sys.path
然后它告诉我
['', '/anaconda3/lib/python37.zip', '/anaconda3/lib/python3.7', '/anaconda3/lib/python3.7/lib-dynload', '/anaconda3/lib/python3.7/site-packages', '/anaconda3/lib/python3.7/site-packages/aeosa']
退出python3,我又
$ pip install pillow
(因为这样可以让pip告诉你pillow装在哪里了)
然后它说
Requirement already satisfied: pillow in /usr/local/lib/python2.7/site-packages (5.3.0)
进去一看,还真有(在这之前我还查了一下为什么我的mac看不到usr文件夹,我是有多菜……,其实查之前我还查了一下mac咋进入根目录……)
点进去一看,PIL很大的样子,pillow只有几个文件,我猜是用来给python3.x适配的,看来这个PIL必须要和pillow在一起python3.x才能用
现在pillow和PIL不在python3默认的模块路径里,我就把它复制过去呗
然后它又报错了
ImportError: dlopen(/Users/blind/Desktop/python/newbie/PIL/_imaging.so, 2): Symbol not found: _PyInt_AsLong
Referenced from: /Users/blind/Desktop/python/newbie/PIL/_imaging.so
Expected in: flat namespace
干啊,这又是为啥啊!
在stackoverflow上查了一下这个错误,突然明白我为什么是智障了……
下载pillow时的命令应该是
pip3 install pillow
应该用pip3,而不是pip!!!
我再pip3一遍,发现针对python3的模块文件夹就在python2的右边
把里面的PIL和pillow复制到项目的文件夹下,我再
from PIL import Image, ImageFont, ImageDraw
好感动,终于正常运行了
1.查查pillow模块咋用
发现我们要用到Image, ImageFont, ImageDraw这三个模块以及里面的各种函数
先把用到的函数贴出来,具体咋用后面再讲
- Image模块
函数名 | 解释 |
---|---|
Image.open(“x.x”) | 打开一个图像文件 |
im.size | 它的返回值为宽度和高度的二元组(width, height) |
Image.new(mode, size, color) | 新建一个图像文件 |
im.resize | 缩放 |
- ImageFont模块
函数名 | 解释 |
---|---|
ImageFont.load_default() | 加载一个默认的字体 |
- ImageDraw模块
函数名 | 解释 |
---|---|
Draw(image) | 创建一个可以在给定图像上绘图的对象 |
draw.text(position,string, options) | 在给定的位置绘制一个字符 |
2.开始敲
第一次独立敲python还有点小紧张,之前简单的看了一眼做字符画的教程,因为想满足自己的某种成就感,决定具体的代码还要自己敲!
发现pillow离不开Image类,用Image类的open函数
from PIL import Image
im = Image.open('666.jpg','r')
就能打开项目文件夹下的hhh.jpg文件了
同时我们要获取这个图像的长和宽,用im.size就ok
w,h=im.size
然后顺手再新建一个大小一样的图像,用来储存我们之后画出来的字符画
newIm= Image.new("RGB",im.size, (150, 150, 150))
其中(150,150,150)表示新建图像的背景颜色,因为我有强迫症就选了整数
然后就要我们识别图片里的每一个像素,这里要用到getpixel函数,只要这样
im.getpixel((x, y))
就可以得到某个像素点的颜色,一般返回(r, g, b),然后我们建一个列表color先把每个像素点的RGB参数存下来
再新建一个字符串,每对应一个像素存一个字符,这里我就比较骚了,可以这样玩
char = "ILOVEYOU"
def GetChar(number):
return char[number%8]
然后只要在循环里每次对number加1,就可以连续输出ILOVEYOU了
把每个像素都对应一个字符输出到字符串里,我们就得到了一个文本文件(别忘了敲回车,不然所有像素对应的字符就都在一列了)
然后我们用ImageDraw类的Draw函数,像这样
draw =ImageDraw.Draw(newIm)
就创建了一个可以在上面绘图的对象,以后对图片的处理都在draw这个对象上进行,但newIm也会跟着改变
接下来要获取系统默认的字符信息,分别是字符的宽和高
fontW,fontH=ImageFont.load_default().getsize(char[0])
接下来我们只要把txt中对应的字符串和和colors中每个像素的颜色结合绘制在draw上就完工了
然后运行,干啊,为什么只有原图的一小部分?!
原来是一个像素对应一个字符导致图像太大了
那我们只需要做一些小小的改动
newW = int(w/fontW)
newH = int(h/fontH)
im = im.resize((newW,newH), Image.NEAREST)
把im根据系统默认的字符大小缩放,然后在新的im中获取像素的颜色信息
这次终于成功了!!!
附上代码和图片
# -*- coding:utf-8 -*-
from PIL import Image, ImageFont, ImageDraw
char = "ILOVEYOU"
def GetChar(number):
return char[number%8]
im = Image.open('666.jpg', 'r')
w,h=im.size
newIm = Image.new("RGB", (w,h), (150, 150, 150))
fontW, fontH = ImageFont.load_default().getsize(char[0])
newW = int(w/fontW)
newH = int(h/fontH)
im = im.resize((newW,newH), Image.NEAREST)
txt = ""
colors = []
number = 0
for i in range(newH):
for j in range(newW):
pixel = im.getpixel((j, i))
colors.append((pixel[0], pixel[1], pixel[2]))
txt += GetChar(number)
number += 1
txt += '\n'
colors.append((0, 0, 0))
draw = ImageDraw.Draw(newIm)
x = y = 0
for i in range(len(txt)):
if (txt[i] == '\n'):
x += fontH
y = -fontW
draw.text([y, x], txt[i], colors[i])
y += fontW
newIm.save('999.jpg')
newIm.show()