published on in Python

隐写术・图文隐写术

返回教程主页

上篇 隐写术・QRCode

把图像隐写术与二维码技术结合就能实现将文本内容转换成二维码,然后隐藏到载体图像的图文隐写术。

载入图像并生成二维码

首先,我们需要加载载体图像,并根据指定的文本内容生成二维码:

def gen_qrcode(text:str, side:int):
    image = qrcode.make(text)
    image = image.resize((side, side))
    return image

bg = Image.open('container.jpg')
fg = gen_qrcode('Hello Python!', min(bg.size))

为了确保我们的二维码可以完整的存入载体图像,我们需要缩放二维码使之边长不超过载体图像的最小边城。

将二维码存入载体图像

将二维码存入载体图像的操作和之前的「隐写术・图像隐写术」操作一致。

解析二维码

我们仍旧可以使用之前的「隐写术・图像隐写术」说道操作将二维码取出。在解析二维码时,我们可以使用pyzbar「中文编码可能会有问题」也可以直接用手机扫描。

代码清单

from PIL import Image
import numpy as np
import qrcode


def gen_qrcode(text:str, side:int):
    image = qrcode.make(text)
    image = image.resize((side, side))
    return image

def preprocess(frame:Image.Image):
    image = frame.convert('RGB')
    array = np.array(image)
    array -= array % 2
    return array

def to_binary(frame:Image.Image, threshold:int=127):
    gray   = frame.convert('L')
    array  = np.array(gray)
    binary = (array > threshold).astype(np.uint8)
    return binary

def merge_image(container:np.ndarray, binary:np.ndarray):
    r1, c1 = container.shape[0], container.shape[1]
    r2, c2 = binary.shape[0], binary.shape[1]
    r, c = min(r1, r2), min(c1, c2)
    final = np.copy(container)
    final[:r, :c, :] += binary[:r, :c, None]
    return final

def get_binary(frame:Image.Image):
    array = np.array(frame)
    array %= 2
    array *= 255
    image = Image.fromarray(array)
    return image

bg = Image.open('container.jpg')
fg = gen_qrcode('Hello Python!', min(bg.size))

container = preprocess(bg)
binary = to_binary(fg)

final = merge_image(container, binary)
final_img = Image.fromarray(final)
final_img.save('merged.png')

merged = Image.open('merged.png')
_binary = get_binary(merged)
_binary.show()

from pyzbar.pyzbar import decode

for code in decode(_binary):
    print(code.data.decode())

下篇 隐写术・将游戏存入图像