我使用Python图像库制作了一个Python隐写器。它基本上对图像每个像素中红色内容的最后n个比特中的二进制文本进行编码。这是我的代码,请提出一些改进建议。
from PIL import Image
import os
def str2bin(message):
binary = bin(int.from_bytes(message.encode('utf-8'), 'big'))
return binary[2:]
def bin2str(binary):
n = int(binary, 2)
return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode()
def hide(filename, message, bits=2):
image = Image.open(filename)
binary = str2bin(message) + '00000000'
if (len(binary)) % 8 != 0:
binary = '0'*(8 - ((len(binary)) % 8)) + binary
data = list(image.getdata())
newData = []
index = 0
for pixel in data:
if index < len(binary):
pixel = list(pixel)
pixel[0] >>= bits
pixel[0] <<= bits
pixel[0] += int('0b' + binary[index:index+bits], 2)
pixel = tuple(pixel)
index += bits
newData.append(pixel)
image.putdata(newData)
image.save('\\'.join(filename.split('\\')[0:-1]) + '/coded-'+os.path.basename(filename), 'PNG')
return len(binary)
def unhide(filename, bits=2):
image = Image.open(filename)
data = image.getdata()
binary = ''
index = 0
while not (len(binary) % 8 == 0 and binary[-8:] == '00000000'):
value = '00000000' + bin(data[index][0])[2:]
binary += value[-bits:]
index += 1
message = bin2str(binary)
return message
if __name__ == '__main__':
file = open('tmiab.txt', encoding='utf-8')
hide('E:\\Python\\Steganography\\img.png', file.read(), 2)
print(unhide('E:\\Python\\Steganography\\coded-img.png', 2)[:10000])我能够编码小说中的三个人在一艘船在1600乘1200像素的图像,只需更换最后两位。
我正在寻找一些改进,如减少时间消耗。
请帮帮忙。谢谢。
发布于 2017-06-10 08:12:14
执行list(Image.open(filename).getdata())意味着在开始任何处理之前读取整个图像。这意味着时间和内存开销按像素的顺序排列。看起来,您每次只需要处理一个像素,因此您可以直接迭代getdata()的结果,将像素视为流。在处理更大的数据结构时,这一点变得非常重要,特别是当整个数据无法存储在内存中时。如果getdata()的结果对您的目的不是最好的,那么就会有许多对图像中像素进行迭代的其他方法。迭代文本数据可能不是那么重要(因为数据应该要小得多),但也会比一次性阅读更好。
您目前正在进行许多值转换,从UTF-8字符串到二进制和back,二进制到int和back,以及像素到列表(大概是分离颜色值)。避免这些转换会大大提高程序的速度。一般来说,确定一个单一的“数据交换类型”是个好主意,在这种情况下,整数是一个显而易见的选择--它们很容易映射到文本和像素值,而且处理起来非常快。
您有可选的参数,这些参数除了默认值之外,从来不与任何其他参数一起使用。这增加了混乱,并使我怀疑函数是否会做正确的事情,如果调用其他任何东西。
使用argparse允许指定输入数据文件和图像文件。这使得程序更加通用,可测试性更强。
驱动此代码的测试应该指出该程序的一些限制:
bits > 8怎么办?pep8是一个很好的工具,可以确保您的代码是惯用的Python。例如:在Python变量中,按约定名总是under_scored。
https://codereview.stackexchange.com/questions/165163
复制相似问题