File size: 5,492 Bytes
6528fbf
b2358ad
aa56dd1
 
6528fbf
 
 
aa56dd1
 
2697417
6528fbf
 
 
 
aa56dd1
059deb6
6528fbf
059deb6
839bec8
059deb6
839bec8
059deb6
6528fbf
059deb6
 
 
 
6528fbf
 
 
f00a6e1
6528fbf
 
 
 
 
 
 
 
2697417
6528fbf
 
 
 
 
f00a6e1
6528fbf
839bec8
f00a6e1
 
 
 
 
 
6528fbf
839bec8
 
6528fbf
 
2697417
6528fbf
839bec8
 
6528fbf
 
 
839bec8
2697417
839bec8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6528fbf
f00a6e1
6528fbf
059deb6
6528fbf
 
 
 
 
 
 
 
 
 
 
 
839bec8
 
 
6528fbf
839bec8
 
2697417
839bec8
 
6528fbf
839bec8
6528fbf
839bec8
6528fbf
839bec8
6528fbf
 
839bec8
 
 
 
 
 
 
 
 
 
6528fbf
839bec8
 
 
6528fbf
 
 
 
 
 
 
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import cv2
import numpy as np
from PIL import Image, PngImagePlugin

def png_encode(im_name, extra):
    """Encode watermark using PNG metadata"""
    try:
        im = Image.open(im_name)
        info = PngImagePlugin.PngInfo()
        info.add_text("TXT", extra)
        im.save("test.png", pnginfo=info)
        return "test.png", "Watermark added successfully"
    except Exception as e:
        return im_name, f"Error adding watermark: {str(e)}"

def to_bin(data):
    """Convert data to binary format as string"""
    if isinstance(data, str):
        return ''.join(format(x, '08b') for x in data.encode('utf-8'))
    elif isinstance(data, bytes):
        return ''.join(format(x, '08b') for x 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):
    """Decode watermark from image"""
    try:
        # First try PNG metadata method
        try:
            im = Image.open(image_name)
            if "TXT" in im.info:
                return im.info["TXT"]
        except:
            pass

        # Steganography method
        image = cv2.imread(image_name)
        if image is None:
            raise ValueError("Could not read image file")
            
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        binary_data = ""
        
        # Extract binary data from image
        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]

        # Convert binary string to bytes
        bytes_data = b''
        for i in range(0, len(binary_data), 8):
            byte = binary_data[i:i+8]
            if len(byte) == 8:
                try:
                    byte_val = int(byte, 2)
                    bytes_data += bytes([byte_val])
                except ValueError:
                    continue

        # Try to find the end marker in raw bytes
        try:
            end_marker = b'====='
            if end_marker in bytes_data:
                bytes_data = bytes_data.split(end_marker)[0]
            
            # Try to find the delimiter in raw bytes
            delimiter = b'#####'
            if delimiter in bytes_data:
                bytes_data = bytes_data.split(delimiter)[0]
            
            # Decode the bytes to string
            decoded_text = bytes_data.decode('utf-8', errors='ignore')
            return decoded_text.strip()
            
        except Exception as e:
            print(f"Decoding error: {e}")
            # If regular decoding fails, try character by character
            result = ""
            current_bytes = bytearray()
            
            for byte in bytes_data:
                current_bytes.append(byte)
                try:
                    char = current_bytes.decode('utf-8')
                    result += char
                    current_bytes = bytearray()
                except UnicodeDecodeError:
                    continue
                    
            if result:
                return result.strip()
            return "Error: Could not decode watermark"

    except Exception as e:
        return f"Error detecting watermark: {str(e)}"

def encode(image_name, secret_data, txt=None):
    """Encode watermark using steganography"""
    try:
        image = cv2.imread(image_name)
        if image is None:
            raise ValueError("Could not read image file")
            
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        
        # Calculate maximum bytes that can be encoded
        n_bytes = image.shape[0] * image.shape[1] * 3 // 8
        
        # Prepare the data with delimiters
        secret_data = str(secret_data)
        complete_data = secret_data + "#####" + "====="
        
        # Convert to binary
        binary_secret_data = to_bin(complete_data)
        
        # Check if the data can fit in the image
        if len(binary_secret_data) > n_bytes * 8:
            return image_name, "Watermark is too large for Image Size"
        
        data_index = 0
        binary_len = len(binary_secret_data)
        
        # Embed the data
        for i in range(image.shape[0]):
            for j in range(image.shape[1]):
                if data_index < binary_len:
                    pixel = image[i, j]
                    for color_channel in range(3):
                        if data_index < binary_len:
                            # Get the binary value of the pixel
                            binary_value = format(pixel[color_channel], '08b')
                            # Replace the least significant bit
                            binary_value = binary_value[:-1] + binary_secret_data[data_index]
                            # Update the pixel value
                            image[i, j, color_channel] = int(binary_value, 2)
                            data_index += 1
                else:
                    break
                    
        # Save the result
        output_path = "watermarked_image.png"
        cv2.imwrite(output_path, cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
        return output_path, "Watermark embedded successfully"
        
    except Exception as e:
        return image_name, f"Error encoding watermark: {str(e)}"