把图像隐写术与二维码技术结合就能实现将文本内容转换成二维码,然后隐藏到载体图像的图文隐写术。
载入图像并生成二维码
首先,我们需要加载载体图像,并根据指定的文本内容生成二维码:
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())