图片隐写术:将小说存进图片中

将小说存进图片中

思路来自B站up主:偶尔有点小迷糊
视频链接: 点击前往bilibili
按照up主的思路自己pan逻辑,手敲代码,一些处理可能不够简略
代码如下:

from PIL import Image

a = input("1.小说生成图片\n2.图片还原小说\n3.输出结果比较测试\n输入命令序号:")
if a == '1':
    f = open("斗罗大陆.txt","r")
    txt = f.read()
    # 动态分配图片大小
    box = int(len(txt) ** 0.5) + 1
    img = Image.new("RGBA",(box,box),(255,255,255))
    # x为横轴,y为纵轴
    x = 0
    y = 0
    print("生成图片中 Loading...")
    for t in txt:
        t = str(hex(ord(t)))
        l = len(t) - 2
        list = ["0"]*4
        i = 0
        while i < l:
            list[i+4-l] = t[i+2] # 顺序赋值
            i += 1
        if x == box:
            x = 0
            y += 1
        # 写某个像素位置的值
        img.putpixel((x,y),(255,int(list[0]+list[1],base=16),int(list[2]+list[3],base=16)))
        x += 1
    img.save("小说.png","png")
    f.close()
    print("\n处理完成,输出:小说.png")
elif a == '2':
    im=Image.open("小说.png")
    w, h = im.size
    txt = ""
    # x为横轴,y为纵轴
    y = 0
    print("图片处理中 Loading...")
    while y < h:
        x = 0
        while x < w:
            rgb = im.getpixel((x,y))
            t1 = rgb[1]
            t2 = rgb[2]
            t = t1 * 256 + t2 # 顺序赋值,直接计算
            txt += chr(t)
            x += 1
        y += 1
    f = open("小说.txt","w",encoding="utf-8")
    f.write(txt)
    f.close()
    print("\n处理完成,输出:小说.txt")
elif a == '3':
    f1 = open("斗罗大陆.txt","r")
    f2 = open("小说.txt","r",encoding="utf-8")
    t1 = f1.read()
    t2 = f2.read()
    l1 = len(t1)
    l2 = len(t2)
    i = 0
    a = 0
    print("文本比较中 Loading...")
    while i < l1 and i < l2:
        if t1[i] != t2[i]:
            a += 1
        i += 1
    print("\n字符不同个数为 %d\n文本长度差为 %d"%(a,abs(l1-l2)))

(图片超过上传大小限制了,难受,不然我就发出来了
处理完比较时发现字符都相同,但文本长度有384的差值
个人感觉是txt编码格式问题,我再查查

妈妈再也不用担心我存不了XXX 了,手动滑稽
更新:
上面的问题已经找到,后面自动填充的像素被写进去了
解决方法:加入if判断,退出循环即可
更正代码(双像素)

from PIL import Image

a = input("1.小说生成图片\n2.图片还原小说\n3.输出结果比较测试\n输入命令序号:")
if a == '1':
    f = open("斗罗大陆.txt","r")
    txt = f.read()
    # 动态分配图片大小
    box = int(len(txt) ** 0.5) + 1
    img = Image.new("RGBA",(box,box),(255,255,255))
    # x为横轴,y为纵轴
    x = 0
    y = 0
    print("生成图片中 Loading...")
    for t in txt:
        t = str(hex(ord(t)))
        l = len(t) - 2
        list = ["0"]*4
        i = 0
        while i < l:
            list[i+4-l] = t[i+2] # 顺序赋值
            i += 1
        if x == box:
            x = 0
            y += 1
        # 写某个像素位置的值
        img.putpixel((x,y),(255,int(list[0]+list[1],base=16),int(list[2]+list[3],base=16)))
        x += 1
    img.save("小说.png","png")
    f.close()
    print("\n处理完成,输出:小说.png")
elif a == '2':
    im=Image.open("小说.png")
    w, h = im.size
    txt = ""
    # x为横轴,y为纵轴
    y = 0
    print("图片处理中 Loading...")
    while y < h:
        x = 0
        while x < w:
            rgb = im.getpixel((x,y))
            t1 = rgb[1]
            t2 = rgb[2]
            t = t1 * 256 + t2 # 顺序赋值,直接计算
            # 文字部分已结束 即 t = 255*256+255
            if t == 65535:
                break
            txt += chr(t)
            x += 1
        # 再次判断,跳出大循环
        if t == 65535:
            break
        y += 1
    f = open("小说.txt","w",encoding="utf-8")
    f.write(txt)
    f.close()
    print("\n处理完成,输出:小说.txt")
elif a == '3':
    f1 = open("斗罗大陆.txt","r")
    f2 = open("小说.txt","r",encoding="utf-8")
    t1 = f1.read()
    t2 = f2.read()
    l1 = len(t1)
    l2 = len(t2)
    i = 0
    a = 0
    print("文本比较中 Loading...")
    while i < l1 and i < l2:
        if t1[i] != t2[i]:
            a += 1
        i += 1
    print("\n字符不同个数为 %d\n文本长度差为 %d"%(a,abs(l1-l2)))

在评论区看到alpha通道(透明度)也是最大255的参数
于是又改写了份四参数处理的代码(即一个像素包含两个字符)

from PIL import Image

a = input("1.小说生成图片\n2.图片还原小说\n3.输出结果比较测试\n输入命令序号:")
if a == '1':
    f = open("斗罗大陆.txt","r")
    txt = f.read()
    # 动态分配图片大小
    box = int((len(txt) / 2) ** 0.5) + 1
    img = Image.new("RGBA",(box,box),(0,0,0,0))
    # x为横轴,y为纵轴
    x = 0
    y = 0
    # s为0时写入rg,为1时写入b和alpha通道 
    s = 0
    # 单次计数器
    num = 0
    print("生成图片中 Loading...")
    for t in txt:
        t = str(hex(ord(t)))
        l = len(t) - 2
        list = ["0"]*4
        i = 0
        b = -1
        alpha = -1
        while i < l:
            list[i+4-l] = t[i+2] # 顺序赋值
            i += 1
        if x == box:
            x = 0
            y += 1
        # 写某个像素位置的值
        if list != ["0"]*4:
            if s == 0:
                r = int(list[0]+list[1],base=16)
                g = int(list[2]+list[3],base=16)
                s = 1
            elif s == 1:
                b = int(list[0]+list[1],base=16)
                alpha = int(list[2]+list[3],base=16)
                img.putpixel((x,y),(r,g,b,alpha))
                s = 0
                x += 1
    # 处理奇数长度最后的字符
    if x == box:
        x = 0
        y += 1
    if s == 1:
        img.putpixel((x,y),(r,g,0,0))
    img.save("小说.png","png")
    f.close()
    print("\n处理完成,输出:小说.png")
elif a == '2':
    im=Image.open("小说.png")
    w, h = im.size
    txt = ""
    # x为横轴,y为纵轴
    y = 0
    print("图片处理中 Loading...")
    while y < h:
        x = 0
        while x < w:
            rgba = im.getpixel((x,y))
            t1 = rgba[0] * 256 + rgba[1] # 顺序赋值,直接计算
            t2 = rgba[2] * 256 + rgba[3]
            # 正常情况
            if t1 != 0 and t2 != 0:
                txt += chr(t1)+chr(t2)
            # 剩余一个字符的情况
            elif t2 == 0 and t1 != 0:
                txt += chr(t1)
            # 字符已处理完成
            else:
                break
            x += 1
        y += 1
    f = open("小说.txt","w",encoding="utf-8")
    f.write(txt)
    f.close()
    print("\n处理完成,输出:小说.txt")
elif a == '3':
    f1 = open("斗罗大陆.txt","r")
    f2 = open("小说.txt","r",encoding="utf-8")
    t1 = f1.read()
    t2 = f2.read()
    l1 = len(t1)
    l2 = len(t2)
    i = 0
    a = 0
    print("文本比较中 Loading...")
    while i < l1 and i < l2:
        if t1[i] != t2[i]:
            a += 1
        i += 1
    print("\n字符不同个数为 %d\n文本长度差为 %d"%(a,abs(l1-l2)))

注意:当字符长度为奇数时,最后字符要特殊处理
处理完成的图片比之前的缩小很多,宽高长度大约为原来的二分之根号二
测试结果
字符不同个数为 0,文本长度差为 0(就很舒服)

你可能感兴趣的:(有趣的python,python)