主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Python: ステガノグラフィで画像に画像を埋め込む

                
tags: python
 ググってみたら二番煎じだったネタ……




 二つの画像を見比べる。

150401_foo.png

150401_embedded.png

 ステガノグラフィを利用して、上の画像の画素情報部分にあるJPEGデータを埋め込んだのが下の画像である。ステガノグラフィを使ってるのでファイルサイズが増大なんてこともない。どんなJPEGデータが埋め込まれているかというとこの下のポスター画像で、埋め込まれた画像と上の画像の解像度の差はほとんどない。そんなのが埋め込めるなんてJPEGの圧縮率はやっぱり高い。
150401_thumbnail.jpg

 下にステガノグラフィをPythonで実装したスクリプトを付けておく。実はだいぶ前に書いたものにちょっと手を加えたもの。
http://elicon.blog57.fc2.com/blog-entry-189.html
 埋め込みは"python stegano.py origin.png thumb.jpg"、埋め込んだ画像の取り出しは"python stegano.py embedded.png"でできる。
import sys
import struct

from PIL import Image


def embed(file, thumbnail):
with open(thumbnail, "rb") as f:
data = f.read()
length = struct.pack(">L", len(data))
string = length + data
src = Image.open(file)
newImg = src.convert('RGBA')
width, height = src.size
if width * height < len(string):
raise ValueError("too small size image")
im = newImg.load()
x, y = 0, 0
for value in string:
pixel_data = [0, 0, 0, 0]
binary = bin(ord(value))[2:].zfill(8)
for num in range(4):
bin_val = bin(im[x, y][num])[2:].zfill(8)
manipulated = bin_val[0:6] + binary[2 * num: 2 * num + 2]
new = int(manipulated, 2)
pixel_data[num] = new
im[x, y] = tuple(pixel_data)
x += 1
if x >= width:
x = 0
y += 1
newImg.save("embedded.png")
print("output: embedded.png")


def pick(file):
src = Image.open(file)
if src.mode != "RGBA":
raise ValueError()
width, height = src.size
x, y = 0, 0
im = src.load()

string = b""
for x in range(4):
pixel_data = b""
for num in range(4):
bin_val = bin(im[x, y][num])[2:].zfill(8)
pixel_data += bin_val[6:8]
string += chr(int(pixel_data, 2))
length = struct.unpack(">L", string)[0]

string = b""
x = 4
while length != len(string):
pixel_data = b""
for num in range(4):
bin_val = bin(im[x, y][num])[2:].zfill(8)
pixel_data += bin_val[6:8]
string += chr(int(pixel_data, 2))
x += 1
if x >= width:
x = 0
y += 1
if y >= height:
break
with open("thumbnail.jpg", "wb") as f:
f.write(string)


if __name__=='__main__':
if len(sys.argv) == 3:
embed(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
pick(sys.argv[1])


 どういう実装をしてるか以前に書いてなかったので今回はそのあたりを。
 RGBAチャンネルを持ったPNG画像をロードして、1ピクセルごとに、埋め込みたいデータを1バイトずつうまく埋め込んでいる。
 1バイトのデータを2ビット×4つに分割し、1ピクセルあたりのRGBA各色の値の下位2ビットを上書きする。各色とも下位2ビットが変更されるが、下位2ビットが色の見た目に与える影響は限定的なため、埋め込み前と埋め込み後で画像で見てみると違いを判別することは難しい。

 ステガノグラフィは暗号化の技術として使われるようだが、今回は思い付きをやってみたくてやった。これをそのままセキュリティ関連で使うのは無理があるだろう。
            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。