-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhide_subimage.py
More file actions
86 lines (65 loc) · 2.53 KB
/
hide_subimage.py
File metadata and controls
86 lines (65 loc) · 2.53 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
81
82
83
84
85
86
from PIL import Image
def int_to_string(rgb):
r, g, b = rgb
return ('{0:08b}'.format(r),
'{0:08b}'.format(g),
'{0:08b}'.format(b))
def string_to_int(rgb):
r, g, b = rgb
return (int(r, 2),
int(g, 2),
int(b, 2))
def merge_rgb(rgb1, rgb2):
r1, g1, b1 = rgb1
r2, g2, b2 = rgb2
rgb = (r1[:4] + r2[:4],
g1[:4] + g2[:4],
b1[:4] + b2[:4])
return rgb
def merge_images(img1, img2):
if img2.size[0] > img1.size[0] or img2.size[1] > img1.size[1]:
raise ValueError('Image 2 should not be larger than Image 1!')
# Get the pixel map of the two images
pixel_map1 = img1.load()
pixel_map2 = img2.load()
# Create a new image that will be outputted
new_image = Image.new(img1.mode, img1.size)
pixels_new = new_image.load()
for i in range(img1.size[0]):
for j in range(img1.size[1]):
rgb1 = int_to_string(pixel_map1[i, j])
# Use a black pixel as default
rgb2 = int_to_string((0, 0, 0))
# Check if the pixel map position is valid for the second image
if i < img2.size[0] and j < img2.size[1]:
rgb2 = int_to_string(pixel_map2[i, j])
# Merge the two pixels and convert it to a integer tuple
rgb = merge_rgb(rgb1, rgb2)
pixels_new[i, j] = string_to_int(rgb)
return new_image
def unmerge(img):
# Load the pixel map
pixel_map = img.load()
# Create the new image and load the pixel map
new_image = Image.new(img.mode, img.size)
pixels_new = new_image.load()
# Tuple used to store the image original size
original_size = img.size
for i in range(img.size[0]):
for j in range(img.size[1]):
# Get the RGB (as a string tuple) from the current pixel
r, g, b = int_to_string(pixel_map[i, j])
# Extract the last 4 bits (corresponding to the hidden image)
# Concatenate 4 zero bits because we are working with 8 bit
rgb = (r[4:] + '0000',
g[4:] + '0000',
b[4:] + '0000')
# Convert it to an integer tuple
pixels_new[i, j] = string_to_int(rgb)
# If this is a 'valid' position, store it
# as the last valid position
if pixels_new[i, j] != (0, 0, 0):
original_size = (i + 1, j + 1)
# Crop the image based on the 'valid' pixels
new_image = new_image.crop((0, 0, original_size[0], original_size[1]))
return new_image