forked from srli/image_steganography
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolution.py
More file actions
80 lines (64 loc) · 2.83 KB
/
solution.py
File metadata and controls
80 lines (64 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""A program that encodes and decodes hidden messages in images through LSB steganography"""
from PIL import Image, ImageFont, ImageDraw
import textwrap
def decode_image(file_location="images/encoded_sample.png"):
"""Decodes the hidden message in an image
file_location: the location of the image file to decode. By default is the provided encoded image in the images folder
"""
encoded_image = Image.open(file_location)
red_channel = encoded_image.split()[0]
x_size = encoded_image.size[0]
y_size = encoded_image.size[1]
decoded_image = Image.new("RGB", encoded_image.size)
pixels = decoded_image.load()
for i in range(x_size):
for j in range(y_size):
if bin(red_channel.getpixel((i, j)))[-1] == '0':
pixels[i, j] = (255, 255, 255)
else:
pixels[i, j] = (0,0,0)
decoded_image.save("images/decoded_image.png")
def write_text(text_to_write, image_size):
"""Writes text to an RGB image. Automatically line wraps
text_to_write: the text to write to the image
"""
image_text = Image.new("RGB", image_size)
font = ImageFont.load_default().font
drawer = ImageDraw.Draw(image_text)
#Text wrapping. Change parameters for different text formatting
margin = offset = 10
for line in textwrap.wrap(text_to_write, width=60):
drawer.text((margin,offset), line, font=font)
offset += 10
return image_text
def encode_image(text_to_encode, template_image="images/samoyed.jpg"):
"""Encodes a text message into an image
text_to_encode: the text to encode into the template image
template_image: the image to use for encoding. An image is provided by default.
"""
template_image = Image.open(template_image)
red_template = template_image.split()[0]
green_template = template_image.split()[1]
blue_template = template_image.split()[2]
x_size = template_image.size[0]
y_size = template_image.size[1]
#text draw
image_text = write_text(text_to_encode, template_image.size)
bw_encode = image_text.convert('1')
#encode text into image
encoded_image = Image.new("RGB", (x_size, y_size))
pixels = encoded_image.load()
for i in range(x_size):
for j in range(y_size):
red_template_pix = bin(red_template.getpixel((i,j)))
old_pix = red_template.getpixel((i,j))
tencode_pix = bin(bw_encode.getpixel((i,j)))
if tencode_pix[-1] == '1':
red_template_pix = red_template_pix[:-1] + '1'
else:
red_template_pix = red_template_pix[:-1] + '0'
pixels[i, j] = (int(red_template_pix, 2), green_template.getpixel((i,j)), blue_template.getpixel((i,j)))
encoded_image.save("images/encoded_image.png")
if __name__ == '__main__':
decode_image()
encode_image("hello world")