-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
103 lines (60 loc) · 1.88 KB
/
main.py
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import cv2
import numpy as np
from numpy.core.fromnumeric import ravel
TEXT = "hello world, it's me Mariò"
IMG_PATH = "tree.jpg"
NEW_PATH = "tree_new.png"
NB_BITS = 8
def standerdize_length(caracter):
if len(caracter) < NB_BITS:
return ['0']*(NB_BITS - len(caracter)) + caracter
return caracter
def to_bin(n):
return list(bin(n).replace("0b", ""))
def change_last_bit(value, bit):
value = to_bin(value)
value[-1] = bit
return int("".join(value),2)
def write(text, img_path, new_path):
img = cv2.imread(img_path)
h, v , _ = img.shape
if img is None: print("image empty")
if len(text)+1 > h*v : raise ValueError()
else:
text_bit = []
for char in text:
text_bit += standerdize_length(to_bin(ord(char)))
text_bit = np.array(text_bit + ['0']*NB_BITS)
img_flat = img.ravel()
for i, p in enumerate(text_bit):
img_flat[i] = change_last_bit(img_flat[i], p)
cv2.imwrite(new_path, img)
return img
def extract_text(bits):
low, high = 0, NB_BITS
string = ''
length = len(bits)
while high < length:
string += chr(int("".join(bits[low:high]), 2))
low += NB_BITS
high += NB_BITS
return string
def read(img_path):
img = cv2.imread(img_path)
if img is None : print("image empty")
else:
last_bit = lambda x: '0' if x % 2 == 0 else '1'
nb_zeros = 0
bits = []
for i, num in enumerate(img.reshape(-1)):
l_bit = last_bit(num)
bits.append(l_bit)
if l_bit == '0' : nb_zeros += 1
if i != 0 and (i+1) % NB_BITS == 0:
if nb_zeros == NB_BITS: break
else : nb_zeros = 0
return extract_text(bits)
if __name__ == '__main__':
write(TEXT, IMG_PATH, NEW_PATH)
string = read(NEW_PATH)
print(string)