著作権の目的で、画像に非表示の透かしをどのように挿入しますか?Pythonライブラリを探しています。
どのアルゴリズムを使用していますか?パフォーマンスと効率はどうですか?
ステガノグラフィーを調べてみるとよいでしょう。つまり、画像内にデータを隠しています。より損失の多い形式に変換したり、画像の一部を切り抜いたりしても失われないフォームがあります。
「壊れない」透かしを探しているので、exifまたは画像メタデータに保存されているデータがありません。
ここで返信を待っている間に、ウェブ上でいくつかの興味深いものを見つけました:http: //www.cosy.sbg.ac.at/~pmeerw/Watermarking/
アルゴリズムとその特性(それらが何をし、どれほど壊れにくいか)についてかなり網羅的な修士論文があります。私はそれを深く読む時間がありませんが、これは深刻に見えます。何らかの方法でJPEG圧縮、トリミング、ガンマ補正、またはダウンスケーリングをサポートするアルゴリズムがあります。Cですが、Pythonに移植したり、PythonのCライブラリを使用したりできます。
しかし、それは2001年からであり、この分野では7年は長い時間だと思います:(誰かが似たような最近のものを持っていますか?
次のコードを使用します。PILが必要です:
def reduceOpacity(im, opacity):
"""Returns an image with reduced opacity."""
assert opacity >= 0 and opacity <= 1
if im.mode != 'RGBA':
im = im.convert('RGBA')
else:
im = im.copy()
alpha = im.split()[3]
alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
im.putalpha(alpha)
return im
def watermark(im, mark, position, opacity=1):
"""Adds a watermark to an image."""
if opacity < 1:
mark = reduceOpacity(mark, opacity)
if im.mode != 'RGBA':
im = im.convert('RGBA')
# create a transparent layer the size of the image and draw the
# watermark in that layer.
layer = Image.new('RGBA', im.size, (0,0,0,0))
if position == 'tile':
for y in range(0, im.size[1], mark.size[1]):
for x in range(0, im.size[0], mark.size[0]):
layer.paste(mark, (x, y))
elif position == 'scale':
# scale, but preserve the aspect ratio
ratio = min(float(im.size[0]) / mark.size[0], float(im.size[1]) / mark.size[1])
w = int(mark.size[0] * ratio)
h = int(mark.size[1] * ratio)
mark = mark.resize((w, h))
layer.paste(mark, ((im.size[0] - w) / 2, (im.size[1] - h) / 2))
else:
layer.paste(mark, position)
# composite the watermark with the layer
return Image.composite(layer, im, layer)
img = Image.open('/path/to/image/to/be/watermarked.jpg')
mark1 = Image.open('/path/to/watermark1.png')
mark2 = Image.open('/path/to/watermark2.png')
img = watermark(img, mark1, (img.size[0]-mark1.size[0]-5, img.size[1]-mark1.size[1]-5), 0.5)
img = watermark(img, mark2, 'scale', 0.01)
透かしが薄すぎて見えません。単色の画像だけが実際にそれを示します。これを使用して透かしが表示されない画像を作成できますが、元の画像を使用してビットごとの減算を行うと、透かしがそこにあることを示すことができます。
それがどのように機能するかを知りたい場合は、TylerGriffinPhotography.comにアクセスしてください。サイト上の各画像には2回透かしが入ります。1回は不透明度50%(端から5px)で右下隅に透かしを入れ、もう1回は不透明度1%で画像全体に透かしを入れます(透かしをに拡大縮小する「スケール」を使用)。画像全体)。2番目の不透明度の低い透かしの形状が何であるかを理解できますか?
ステガノグラフィーについて話している場合、これは私がかつて友人のために行った古いあまり派手ではないモジュールです (Python 2.x コード):
from __future__ import division
import math, os, array, random
import itertools as it
import Image as I
import sys
def encode(txtfn, imgfn):
with open(txtfn, "rb") as ifp:
txtdata= ifp.read()
txtdata= txtdata.encode('zip')
img= I.open(imgfn).convert("RGB")
pixelcount= img.size[0]*img.size[1]
## sys.stderr.write("image %dx%d\n" % img.size)
factor= len(txtdata) / pixelcount
width= int(math.ceil(img.size[0]*factor**.5))
height= int(math.ceil(img.size[1]*factor**.5))
pixelcount= width * height
if pixelcount < len(txtdata): # just a sanity check
sys.stderr.write("phase 2, %d bytes in %d pixels?\n" % (len(txtdata), pixelcount))
sys.exit(1)
## sys.stderr.write("%d bytes in %d pixels (%dx%d)\n" % (len(txtdata), pixelcount, width, height))
img= img.resize( (width, height), I.ANTIALIAS)
txtarr= array.array('B')
txtarr.fromstring(txtdata)
txtarr.extend(random.randrange(256) for x in xrange(len(txtdata) - pixelcount))
newimg= img.copy()
newimg.putdata([
(
r & 0xf8 |(c & 0xe0)>>5,
g & 0xfc |(c & 0x18)>>3,
b & 0xf8 |(c & 0x07),
)
for (r, g, b), c in it.izip(img.getdata(), txtarr)])
newimg.save(os.path.splitext(imgfn)[0]+'.png', optimize=1, compression=9)
def decode(imgfn, txtfn):
img= I.open(imgfn)
with open(txtfn, 'wb') as ofp:
arrdata= array.array('B',
((r & 0x7) << 5 | (g & 0x3) << 3 | (b & 0x7)
for r, g, b in img.getdata())).tostring()
findata= arrdata.decode('zip')
ofp.write(findata)
if __name__ == "__main__":
if sys.argv[1] == 'e':
encode(sys.argv[2], sys.argv[3])
elif sys.argv[1] == 'd':
decode(sys.argv[2], sys.argv[3])
画像ピクセルごとに 1 バイトのデータを格納します: 青バンドの最下位 3 ビット、緑バンドの 2 LSB、赤バンドの 3 LSB。
エンコード機能: 入力テキスト ファイルは zlib によって圧縮され、圧縮されたバイトと少なくとも同じ数のピクセルが存在するように入力画像のサイズが変更されます (比率を維持します)。入力画像と同じ名前のPNG画像 (コードをそのままにしておく場合は、「.png」ファイル名を入力として使用しないでください:) が保存され、ステガノグラフィック データが含まれます。
デコード関数: 以前に保存された zlib 圧縮データが入力画像から抽出され、指定されたファイル名で非圧縮で保存されます。
古いコードがまだ実行されていることを確認したので、ステガノグラフィ データを含む画像の例を次に示します。
追加されたノイズがほとんど見えないことに気付くでしょう。
まあ、目に見えない透かしはそれほど簡単ではありません。digimarcをチェックしてください、彼らはそれでどんなお金を稼ぎましたか。孤独な天才が書いた無料のC/Pythonコードはなく、無料で使用できます。私は独自のアルゴリズムを実装しました。ツールの名前はSignMyImageです。興味があればグーグルで…F>
新しい (2005) 電子透かしに関する FAQ がwatermarkingworld.orgにあります。
エクシフは?おそらくあなたが考えているほど安全ではありませんが、ほとんどのユーザーはそれが存在することさえ知りません.
これをすぐに実行できるライブラリはないと思います。独自のものを実装したい場合は、間違いなくPython Imaging Library (PIL) を使用します。
これは、PIL を使用して可視透かしを画像に追加するPython クックブック レシピです。必要に応じて十分な場合は、これを使用して、探しているものがわかっている場合にのみ表示される十分な透明度を持つ透かしを追加できます。
一部の画像形式には、任意の情報も格納できるヘッダーがあります。
たとえば、PNG 仕様には、テキスト データを格納できるチャンクがあります。これは上記の回答と似ていますが、画像データ自体にランダム データを追加していません。
うーんに似た回答を投稿するつもりでした。画像ソースを説明する小さな TXT ファイル (および、該当する場合はおそらく小さな著作権ステートメント) を、検出や解読が困難な方法で画像に挿入することをお勧めします。
壊れないことがどれほど重要かはわかりませんが、簡単な解決策は、画像の最後にテキスト ファイルを追加することかもしれません。「この画像は~のものです」みたいな。
ビューア/ブラウザで画像を開くと普通の jpeg のように見えますが、テキスト エディタで開くと最後の行が読めます。
同じ方法で、実際のファイルをイメージに含めることができます。(画像内にファイルを隠す) 少し当たり外れがあることがわかりましたが、7-zip ファイルは機能しているようです。あらゆる種類のコピーライト機能を画像内に隠すことができます。
繰り返しになりますが、どんなに想像しても壊れないわけではありませんが、肉眼では完全に見えません。