Support hide/reveal for image byte objects

This commit is contained in:
Andy Roberts 2017-01-18 20:39:37 +00:00
parent 5b362403db
commit 486358de69
2 changed files with 31 additions and 4 deletions

View file

@ -27,7 +27,7 @@ __license__ = "GPLv3"
from PIL import Image from PIL import Image
import piexif import piexif
def hide(input_image_file, img_enc, secret_message = None, secret_file = None): def hide(input_image_file, img_enc, secret_message = None, secret_file = None, img_format = None):
""" """
Hide a message (string) in an image. Hide a message (string) in an image.
""" """
@ -44,6 +44,10 @@ def hide(input_image_file, img_enc, secret_message = None, secret_file = None):
text = compress(b64encode(secret_message)) text = compress(b64encode(secret_message))
img = Image.open(input_image_file) img = Image.open(input_image_file)
if img_format is None:
img_format = img.format
if "exif" in img.info: if "exif" in img.info:
exif_dict = piexif.load(img.info["exif"]) exif_dict = piexif.load(img.info["exif"])
else: else:
@ -51,7 +55,7 @@ def hide(input_image_file, img_enc, secret_message = None, secret_file = None):
exif_dict["0th"] = {} exif_dict["0th"] = {}
exif_dict["0th"][piexif.ImageIFD.ImageDescription] = text exif_dict["0th"][piexif.ImageIFD.ImageDescription] = text
exif_bytes = piexif.dump(exif_dict) exif_bytes = piexif.dump(exif_dict)
img.save(img_enc, exif=exif_bytes) img.save(img_enc, format=img_format, exif=exif_bytes)
img.close() img.close()
return img return img
@ -63,8 +67,20 @@ def reveal(input_image_file):
from base64 import b64decode from base64 import b64decode
from zlib import decompress from zlib import decompress
exif_dict = piexif.load(input_image_file) img = Image.open(input_image_file)
encoded_message = exif_dict["0th"][piexif.ImageIFD.ImageDescription] try:
if img.format in ['JPEG', 'TIFF']:
if 'exif' in img.info:
exif_dict = piexif.load(img.info.get("exif", b''))
description_key = piexif.ImageIFD.ImageDescription
encoded_message = exif_dict["0th"][description_key]
else:
encoded_message = b''
else:
raise ValueError("Given file is neither JPEG nor TIFF.")
finally:
img.close()
return b64decode(decompress(encoded_message)) return b64decode(decompress(encoded_message))

View file

@ -26,6 +26,7 @@ __license__ = "GPLv3"
import os import os
import unittest import unittest
import io
from stegano import exifHeader from stegano import exifHeader
@ -82,6 +83,16 @@ class TestEXIFHeader(unittest.TestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
clear_message = exifHeader.reveal("./image.png") clear_message = exifHeader.reveal("./image.png")
def test_with_bytes(self):
outputBytes = io.BytesIO()
message = b"Secret"
exifHeader.hide("./tests/sample-files/20160505T130442.jpg",
outputBytes,
secret_message=message)
clean_message = exifHeader.reveal(outputBytes)
self.assertEqual(message, clean_message)
def tearDown(self): def tearDown(self):
try: try:
os.unlink("./image.jpg") os.unlink("./image.jpg")