mirror of
https://github.com/KevinMidboe/knowit_julekalender-2018.git
synced 2025-10-29 17:50:19 +00:00
Submission for decoding steganography image
This commit is contained in:
BIN
luke_04/images/input-pokemon_jakt.png
Normal file
BIN
luke_04/images/input-pokemon_jakt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
BIN
luke_04/images/output-pokemon_jakt.png
Normal file
BIN
luke_04/images/output-pokemon_jakt.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
55
luke_04/steganography.py
Normal file
55
luke_04/steganography.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
from PIL import Image
|
||||||
|
import numpy as np
|
||||||
|
import itertools
|
||||||
|
|
||||||
|
input_image = os.path.join(os.path.dirname(__file__), 'images/input-pokemon_jakt.png')
|
||||||
|
output_image = os.path.join(os.path.dirname(__file__), 'images/output-pokemon_jakt.png')
|
||||||
|
|
||||||
|
def main():
|
||||||
|
LSB = 4
|
||||||
|
image = Image.open(input_image)
|
||||||
|
pixels = np.array(image)
|
||||||
|
width, height, channels = pixels.shape
|
||||||
|
|
||||||
|
for i,j,k in [(i,j,k) for i in range(width) for j in range(height) for k in range(channels)]:
|
||||||
|
value = int(f'{pixels[i][j][k]:b}'[-LSB:], 2)
|
||||||
|
pixels[i,j,k] = (255 // 2**LSB) * value
|
||||||
|
|
||||||
|
image = Image.fromarray(pixels)
|
||||||
|
image.save(output_image)
|
||||||
|
return output_image
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
_____
|
||||||
|
tests
|
||||||
|
|
||||||
|
* compare the hash values of images
|
||||||
|
* compare all bits in every channel
|
||||||
|
calls = [hashCompare]
|
||||||
|
'''
|
||||||
|
|
||||||
|
'''
|
||||||
|
___
|
||||||
|
previous attempts
|
||||||
|
|
||||||
|
for i, j, in itertools.product(width, height, channels):
|
||||||
|
encoded_value = int(f'{pixels[i][j][k]:b}'[-LSB:], 2)
|
||||||
|
rbg_lsb_ratio = 255 // 2**LSB
|
||||||
|
pixels[i][j][k] = rbg_lsb_ratio * encoded_value
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(width):
|
||||||
|
for j in range(height):
|
||||||
|
for k in range(channels):
|
||||||
|
encoded_value = int(f'{pixels[i][j][k]:b}'[-LSB:], 2)
|
||||||
|
rbg_lsb_ratio = 255 // 2**LSB
|
||||||
|
pixels[i][j][k] = rbg_lsb_ratio * encoded_value
|
||||||
|
|
||||||
|
'''
|
||||||
88
luke_04/stenogram.py
Normal file
88
luke_04/stenogram.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
"""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]
|
||||||
|
green_channel = encoded_image.split()[1]
|
||||||
|
blue_channel = encoded_image.split()[2]
|
||||||
|
|
||||||
|
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):
|
||||||
|
r_pixel = red_channel.getpixel((i,j))
|
||||||
|
g_pixel = green_channel.getpixel((i,j))
|
||||||
|
b_pixel = blue_channel.getpixel((i,j))
|
||||||
|
# if pixels[i, j] = r_pixel, g_pixel, b_pixel ? bin(red_pixel)[-1] == '0':
|
||||||
|
if bin(r_pixel)[-1] == '0' or bin(g_pixel)[-1] == '0' or bin(b_pixel)[-1] == '0':
|
||||||
|
pixels[i, j] = (r_pixel, g_pixel, b_pixel)
|
||||||
|
else:
|
||||||
|
pixels[i, j] = (255,255,255)
|
||||||
|
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)))
|
||||||
|
green_template_pix = bin(green_template.getpixel((i,j)))
|
||||||
|
blue_template_pix = bin(blue_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'
|
||||||
|
green_template_pix = green_template_pix[:-1] + '1'
|
||||||
|
blue_template_pix = blue_template_pix[:-1] + '1'
|
||||||
|
else:
|
||||||
|
red_template_pix = red_template_pix[:-1] + '0'
|
||||||
|
green_template_pix = green_template_pix[:-1] + '0'
|
||||||
|
blue_template_pix = blue_template_pix[:-1] + '0'
|
||||||
|
pixels[i, j] = (int(red_template_pix, 1), int(green_template_pix, 1), int(blue_template_pix, 1))
|
||||||
|
|
||||||
|
encoded_image.save("images/encoded_image.png")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
decode_image()
|
||||||
|
# encode_image("hello world")
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from luke_04.LSB import main
|
from luke_04.steganography import main
|
||||||
|
|
||||||
path = os.path.dirname(__file__)
|
path = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user