File size: 3,314 Bytes
1618e9b
b2358ad
aa56dd1
1618e9b
 
aa56dd1
1618e9b
 
aa56dd1
 
 
1618e9b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aa56dd1
 
059deb6
 
1618e9b
059deb6
1618e9b
059deb6
1618e9b
059deb6
 
 
 
1618e9b
 
 
f00a6e1
 
1618e9b
f00a6e1
 
 
 
 
 
 
1618e9b
f00a6e1
 
 
 
 
1618e9b
 
f00a6e1
1618e9b
 
059deb6
1618e9b
 
7b01ac4
1618e9b
059deb6
 
1618e9b
059deb6
1618e9b
059deb6
1618e9b
 
 
059deb6
1618e9b
 
059deb6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1618e9b
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
import cv2
import numpy as np
from PIL import Image, PngImagePlugin
import os
import uuid

def png_encode(im_name, extra):
    try:
        im = Image.open(im_name)
        info = PngImagePlugin.PngInfo()
        info.add_text("TXT", extra)

        unique_id = str(uuid.uuid4())[:8]
        filename, ext = os.path.splitext(im_name)
        new_filename = f"{filename}_{unique_id}{ext}"
        im.save(new_filename, pnginfo=info)

        width, height = im.size
        rect_width, rect_height = 200, 50
        x = width - rect_width - 10
        y = height - rect_height - 10
        png_encode_coords = (x, y, rect_width, rect_height)

        return new_filename, "", png_encode_coords

    except Exception as e:
        return None, str(e), None


def to_bin(data):
    if isinstance(data, str):
        return ''.join([format(ord(i), "08b") for i in data])
    elif isinstance(data, bytes):
        return ''.join([format(i, "08b") for i in data])
    elif isinstance(data, np.ndarray):
        return [format(i, "08b") for i in data]
    elif isinstance(data, int) or isinstance(data, np.uint8):
        return format(data, "08b")
    else:
        raise TypeError("Type not supported.")


def decode(image_name, txt=None):
    try:
        BGRimage = cv2.imread(f"{image_name}")
        image = cv2.cvtColor(BGRimage, cv2.COLOR_BGR2RGB)
        binary_data = ""
        for row in image:
            for pixel in row:
                r, g, b = to_bin(pixel)
                binary_data += r[-1]
                binary_data += g[-1]
                binary_data += b[-1]
        all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)]
        decoded_data = ""
        for byte in all_bytes:
            decoded_data += chr(int(byte, 2))
            if decoded_data[-5:] == "=====":
                break
        this = decoded_data[:-5].split("#####", 1)[0]
        return this
    except Exception as e:
        return str(e)


def encode(image_name, secret_data, txt=None):
    msg = ""
    BGRimage = cv2.imread(f"{image_name}")
    image = cv2.cvtColor(BGRimage, cv2.COLOR_BGR2RGB)
    n_bytes = image.shape[0] * image.shape[1] * 3 // 8
    print("[*] Maximum bytes to encode:", n_bytes)
    secret_data1 = secret_data
    while True:
        if len(secret_data1) + 5 < (n_bytes):
            secret_data1 = f'{secret_data1}#####'
        elif len(secret_data1) + 5 >= (n_bytes):
            break
    secret_data = secret_data1
    if len(secret_data) > n_bytes:
        msg = "Watermark is too large for Image Size"
        return image_name, msg
    secret_data += "====="
    data_index = 0
    binary_secret_data = to_bin(secret_data)
    data_len = len(binary_secret_data)
    for row in image:
        for pixel in row:
            r, g, b = to_bin(pixel)
            if data_index < data_len:
                pixel[0] = int(r[:-1] + binary_secret_data[data_index], 2)
                data_index += 1
            if data_index < data_len:
                pixel[1] = int(g[:-1] + binary_secret_data[data_index], 2)
                data_index += 1
            if data_index < data_len:
                pixel[2] = int(b[:-1] + binary_secret_data[data_index], 2)
                data_index += 1
            if data_index >= data_len:
                break
    return image, msg