使用 Pillow 创建隐写隐藏图像
Create a steganographically hidden image with Pillow
我正在尝试学习如何创建一组像这样的图像:this。这个想法是有两个看似随机的图像,但是当你对它们进行异或时,你会发现一个秘密信息。我想使用 Python Pillow,可能还需要像 paint.net 这样的简单图像编辑器。所以我的问题由几个部分组成:
- 如何在 Pillow 中生成充满随机黑色或白色像素的图像。
- 我如何才能确保图像的某些区域实际上不是随机的,而是完全相同的,从而确保 XOR 比较能够揭示它们。
创建这些图像的过程非常简单。这是一个如何做到的例子(不是最有效的):
- 创建两个相同大小的输出图像
- 创建一个相同大小的模板,其中 1(白色)表示前景(隐藏消息),0(黑色)表示背景(纯随机)。
- 在一个循环中迭代图像和模板:
- 如果当前位置的模板为 0,则绘制两个随机数(零或一)并将它们分配给每个输出图像的当前像素
- 如果模板说 1,则只绘制一个随机数并将其分配给两个像素
我不会详细介绍您如何读取模板图像、创建二进制输出图像并使用 Pillow 对其进行迭代,因为我从未尝试过 Pillow。然而绘制随机数非常简单:
x = random.randint(0,1)
(参见https://docs.python.org/2/library/random.html#random.randint)
为了让您入门,这里有一种制作随机二值图像的方法:
from PIL import Image
import numpy as np
# Make lots of ones and zeros.
data = np.random.randint(2, size=(100,100))
# Cast as 8-bit ints, 0 and 255.
data = data.astype(np.uint8) * 255
# Cast as an image. Pillow guesses mode.
img = Image.fromarray(data)
结果(放大到300×300像素):
为了后代,我是这样做的:
首先,我制作了一个蒙版图像。它是白色背景,带有红色框和框内的黑色文本。看起来像这样:
这是我编写的用于制作两个模糊图像的脚本:
from PIL import Image
import random
WHITE = (255, 255, 255, 255)
RED = (255, 0, 0, 255)
BLACK = (0, 0, 0, 255)
wb = [WHITE,BLACK]
rng = random.SystemRandom()
orig = Image.open('mask.png')
origData = list(orig.getdata())
n1 = Image.new(orig.mode, orig.size)
n2 = Image.new(orig.mode, orig.size)
n1data = []
n2data = []
for x in origData:
if x == WHITE:
n1data.append(rng.choice(wb))
n2data.append(rng.choice(wb))
elif x == RED:
y = bool(rng.getrandbits(1))
if y:
n1data.append(WHITE)
n2data.append(BLACK)
else:
n1data.append(BLACK)
n2data.append(WHITE)
elif x == BLACK:
y = bool(rng.getrandbits(1))
if y:
n1data.append(WHITE)
n2data.append(WHITE)
else:
n1data.append(BLACK)
n2data.append(BLACK)
n1.putdata(n1data)
n2.putdata(n2data)
n1.save('n1.png')
n2.save('n2.png')
orig.close()
n1.close()
n2.close()
结果如下:
将它们异或在一起,你会得到:
我正在尝试学习如何创建一组像这样的图像:this。这个想法是有两个看似随机的图像,但是当你对它们进行异或时,你会发现一个秘密信息。我想使用 Python Pillow,可能还需要像 paint.net 这样的简单图像编辑器。所以我的问题由几个部分组成:
- 如何在 Pillow 中生成充满随机黑色或白色像素的图像。
- 我如何才能确保图像的某些区域实际上不是随机的,而是完全相同的,从而确保 XOR 比较能够揭示它们。
创建这些图像的过程非常简单。这是一个如何做到的例子(不是最有效的):
- 创建两个相同大小的输出图像
- 创建一个相同大小的模板,其中 1(白色)表示前景(隐藏消息),0(黑色)表示背景(纯随机)。
- 在一个循环中迭代图像和模板:
- 如果当前位置的模板为 0,则绘制两个随机数(零或一)并将它们分配给每个输出图像的当前像素
- 如果模板说 1,则只绘制一个随机数并将其分配给两个像素
我不会详细介绍您如何读取模板图像、创建二进制输出图像并使用 Pillow 对其进行迭代,因为我从未尝试过 Pillow。然而绘制随机数非常简单:
x = random.randint(0,1)
(参见https://docs.python.org/2/library/random.html#random.randint)
为了让您入门,这里有一种制作随机二值图像的方法:
from PIL import Image
import numpy as np
# Make lots of ones and zeros.
data = np.random.randint(2, size=(100,100))
# Cast as 8-bit ints, 0 and 255.
data = data.astype(np.uint8) * 255
# Cast as an image. Pillow guesses mode.
img = Image.fromarray(data)
结果(放大到300×300像素):
为了后代,我是这样做的:
首先,我制作了一个蒙版图像。它是白色背景,带有红色框和框内的黑色文本。看起来像这样:
这是我编写的用于制作两个模糊图像的脚本:
from PIL import Image
import random
WHITE = (255, 255, 255, 255)
RED = (255, 0, 0, 255)
BLACK = (0, 0, 0, 255)
wb = [WHITE,BLACK]
rng = random.SystemRandom()
orig = Image.open('mask.png')
origData = list(orig.getdata())
n1 = Image.new(orig.mode, orig.size)
n2 = Image.new(orig.mode, orig.size)
n1data = []
n2data = []
for x in origData:
if x == WHITE:
n1data.append(rng.choice(wb))
n2data.append(rng.choice(wb))
elif x == RED:
y = bool(rng.getrandbits(1))
if y:
n1data.append(WHITE)
n2data.append(BLACK)
else:
n1data.append(BLACK)
n2data.append(WHITE)
elif x == BLACK:
y = bool(rng.getrandbits(1))
if y:
n1data.append(WHITE)
n2data.append(WHITE)
else:
n1data.append(BLACK)
n2data.append(BLACK)
n1.putdata(n1data)
n2.putdata(n2data)
n1.save('n1.png')
n2.save('n2.png')
orig.close()
n1.close()
n2.close()
结果如下:
将它们异或在一起,你会得到: