先贴代码
from PIL import Image from os import walk from os import getcwd from re import findall code = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'.''' ''' 需要有一个名为input的文件夹存放源图片文件 需要有一个与input文件夹同级的文件夹out存放导出文件 请将本程序放在与input文件夹同级的位置 ''' ''' 当图片只有一张时,请将其命名为数字或含有数字的字符串 当图片不止一张时,如不需要图片有顺序,则可依照上面情况命名 如需要图片有顺序,则全选图片,统一将其命名为一个任意英文字母,此时Windows系统会自动加入序号 图片的修改是无顺序的(东一个西一个),但最终导出的图片是有顺序的 目前只在Windows系统下运行 ''' class PictureToTxt: files1=None def GetName(self,address=getcwd()+"\\input"): for a, b, files2 in walk(address): self.files1=files2 def GetTxt(self,c=210,k=63): txt="" for d in self.files1: image = Image.open(getcwd()+"\\input\\"+d).convert("L").resize((c, k)) h = image.size[1] w = image.size[0] for y in range(h): for x in range(w): color = image.getpixel((x, y)) color = int(color / 256 * len(code)) char = code[color - 1] txt += char txt += "" txt += "\n" for g in findall("\d+", d): pass with open(getcwd()+"\\out\\"+g+".txt", "w", encoding="UTF-8") as file: file.write(txt) txt = "" if __name__ == '__main__': picturetotxt=PictureToTxt() picturetotxt.GetName() picturetotxt.GetTxt()
有点长
用了一些面向对象的玩意
这个程序的运行是要有规范的
''' 需要有一个名为input的文件夹存放源图片文件 需要有一个与input文件夹同级的文件夹out存放导出文件 请将本程序放在与input文件夹同级的位置 ''' ''' 当图片只有一张时,请将其命名为数字或含有数字的字符串 当图片不止一张时,如不需要图片有顺序,则可依照上面情况命名 如需要图片有顺序,则全选图片,统一将其命名为一个任意英文字母,此时Windows系统会自动加入序号 图片的修改是无顺序的(东一个西一个),但最终导出的图片是有顺序的 目前只在Windows系统下运行 '''
上几张图就知道是怎么一回事了
所需模块:
PIL的Image
os的walk和getcwd
re的findall
原理:
从一个文件夹中遍历所有图片的名字
用Image.open()打开图片,转换成灰度模式并获取每一个图片的大小
遍历每一个像素点的灰度值,并进行计算,得到对应的字符(下文具体讲解)
将图片的名字取出,过滤掉字符,只留下数字,导出以该数字为名称的txt文件
第一步:导入模块
第二步:声明一个重要变量
code = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'.'''
code:参与转换计算的字符集,从左到右醒目程度逐渐减小(黑底白字)
第三步:写个类
class PictureToTxt: files1=None
files1:程序遍历图片所在文件夹后返回的所有图片名称(列表)
类里面的第一个方法:
def GetName(self,address=getcwd()+"\\input"): for a, b, files2 in walk(address): self.files1=files2
这个是获取所有图片名字的方法,如果已经有名字的列表了,就不使用这个方法
类里面的第二个方法:
def GetTxt(self,c=210,k=63): txt="" for d in self.files1: image = Image.open(getcwd()+"\\input\\"+d).convert("L").resize((c, k)) h = image.size[1] w = image.size[0] for y in range(h): for x in range(w): color = image.getpixel((x, y)) color = int(color / 256 * len(code)) char = code[color - 1] txt += char txt += "" txt += "\n" for g in findall("\d+", d): pass with open(getcwd()+"\\out\\"+g+".txt", "w", encoding="UTF-8") as file: file.write(txt) txt = ""
txt:要写入.txt文件的字符串,需要先声明
详细说明:
for d in self.files1:
这句代码是把名字列表中的一个取出来
image = Image.open(getcwd()+"\\input\\"+d).convert("L").resize((c, k))
这句是从与这张代码同级的文件夹input中打开以……为名字的图片,然后转为灰度
(这句是\\从\\与这张代码同级的文件夹input中\\打开\\以……为名字的图片)
c和k可以按照图片原大小取值,这里是最适合控制台输出字符画的大小
如果按照原图片大小取值,就要多一步
image1=Image.open(getcwd()+"\\input\\"+d).convert("L") image = image1.resize(image1.size)
h = image.size[1] w = image.size[0]
获取图片的长和宽
for y in range(h): for x in range(w): color = image.getpixel((x, y)) color = int(color / 256 * len(code)) char = code[color - 1] txt += char txt += "" txt += "\n"
第一个for是行,第二个for是列
遍历像素点的灰度值,将灰度值除以256,得到一个比例,再将这个比例对应到字符集上,就是乘以字符集的长度
将对应的结果减一,因为字符集的索引是从0开始的
最后把字符加到txt中,当一行输完后加一个\n
for g in findall("\d+", d): pass
这个是滤除图片的非数字字符,只保留数字,这样才能对应图片的名字中的序号生成txt文件
with open(getcwd()+"\\out\\"+g+".txt", "w", encoding="UTF-8") as file: file.write(txt)
打开一个以……为名字(名字是上面的g)新的txt文件,写入txt数据
txt = ""
这一步至关重要,就是清除字符串txt里面的内容,如果不清除,那么上一张图片的内容会保留到下一张来
第四步:调用
if __name__ == '__main__': picturetotxt=PictureToTxt() picturetotxt.GetName() picturetotxt.GetTxt()
看下结果
把修改过的保留原图片大小的也拿出来
from PIL import Image from os import walk from os import getcwd from re import findall code = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'.@''' ''' 需要有一个名为input的文件夹存放源图片文件 需要有一个与input文件夹同级的文件夹out存放导出文件 请将本程序放在与input文件夹同级的位置 ''' ''' 当图片只有一张时,请将其命名为数字或含有数字的字符串 当图片不止一张时,如不需要图片有顺序,则可依照上面情况命名 如需要图片有顺序,则全选图片,统一将其命名为一个任意英文字母,此时Windows系统会自动加入序号 图片的修改是无顺序的(东一个西一个),但最终导出的图片是有顺序的 目前只在Windows系统下运行 ''' class PictureToTxt: files1=None def GetName(self,address=getcwd()+"\\input"): for a, b, files2 in walk(address): self.files1=files2 def GetTxt(self): txt="" for d in self.files1: image1=Image.open(getcwd()+"\\input\\"+d).convert("L") image = image1.resize(image1.size) h = image.size[1] w = image.size[0] for y in range(h): for x in range(w): color = image.getpixel((x, y)) color = int(color / 256 * len(code)) char = code[color - 1] txt += char txt += "" txt += "\n" for g in findall("\d+", d): pass with open(getcwd()+"\\out\\"+g+".txt", "w", encoding="UTF-8") as file: file.write(txt) txt = "" if __name__ == '__main__': picturetotxt=PictureToTxt() picturetotxt.GetName() picturetotxt.GetTxt()