noumanjavaid commited on
Commit
66655a5
·
verified ·
1 Parent(s): 39dd6f5

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +65 -49
utils.py CHANGED
@@ -5,90 +5,107 @@ import os
5
  import uuid
6
 
7
  def to_bin(data):
 
8
  if isinstance(data, str):
9
- return ''.join([format(ord(i), "08b") for i in data])
10
  elif isinstance(data, bytes):
11
- return ''.join([format(i, "08b") for i in data])
12
  elif isinstance(data, np.ndarray):
13
- return [format(i, "08b") for i in data]
14
  elif isinstance(data, int) or isinstance(data, np.uint8):
15
- return format(data, "08b")
16
  else:
17
  raise TypeError("Type not supported.")
18
 
19
  def encode(image_path, secret_data):
 
20
  try:
21
  # Read the image
22
  image = cv2.imread(image_path)
23
  if image is None:
24
  return None, "Failed to read image"
25
-
26
  # Calculate maximum bytes for encoding
27
- n_bytes = image.shape[0] * image.shape[1] * 3 // 8
28
 
29
- # Check if the secret data is too large
30
- secret_data_with_delimiter = f'{secret_data}#####'
31
- if len(secret_data_with_delimiter) + 5 >= n_bytes:
32
- return None, "Watermark is too large for Image Size"
33
-
34
- # Add ending delimiter
35
- secret_data_with_delimiter += "====="
36
 
37
  # Convert data to binary
38
- binary_secret_data = to_bin(secret_data_with_delimiter)
39
  data_len = len(binary_secret_data)
 
 
 
40
  data_index = 0
41
 
42
- # Encode the data into the image
43
- for i in range(image.shape[0]):
44
- for j in range(image.shape[1]):
45
- pixel = image[i, j]
46
- for color_channel in range(3):
47
- if data_index < data_len:
48
- # Get the binary value of the pixel
49
- binary_value = to_bin(pixel[color_channel])
50
- # Replace the least significant bit
51
- new_binary = binary_value[:-1] + binary_secret_data[data_index]
52
- # Update the pixel with the new value
53
- pixel[color_channel] = int(new_binary, 2)
54
- data_index += 1
55
- image[i, j] = pixel
56
- if data_index >= data_len:
57
- break
58
  if data_index >= data_len:
59
  break
60
-
61
- return image, None
 
 
 
 
 
 
 
 
 
 
 
 
62
  except Exception as e:
63
  return None, f"Error during encoding: {str(e)}"
64
 
65
  def decode(image_path):
 
66
  try:
67
  # Read the image
68
- image = cv2.imread(image_path)
 
 
 
 
 
69
  if image is None:
70
  return "Failed to read image"
71
-
72
  binary_data = ""
73
- for row in image:
74
- for pixel in row:
75
- for color_channel in pixel:
76
- binary_data += to_bin(color_channel)[-1]
 
 
 
77
 
78
  # Convert binary to text
79
- all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)]
80
- decoded_data = ""
81
- for byte in all_bytes:
82
- decoded_data += chr(int(byte, 2))
83
- if decoded_data[-5:] == "=====":
84
- break
 
 
 
 
 
 
85
 
86
- # Remove delimiters
87
- return decoded_data[:-5].split("#####")[0]
88
  except Exception as e:
89
  return f"Error during decoding: {str(e)}"
90
 
91
  def png_encode(im_name, extra):
 
92
  try:
93
  im = Image.open(im_name)
94
  info = PngImagePlugin.PngInfo()
@@ -96,7 +113,7 @@ def png_encode(im_name, extra):
96
 
97
  unique_id = str(uuid.uuid4())[:8]
98
  filename, ext = os.path.splitext(im_name)
99
- new_filename = f"{filename}_{unique_id}{ext}"
100
  im.save(new_filename, "PNG", pnginfo=info)
101
 
102
  width, height = im.size
@@ -107,6 +124,5 @@ def png_encode(im_name, extra):
107
  png_encode_coords = (x, y, rect_width, rect_height)
108
 
109
  return new_filename, None
110
-
111
  except Exception as e:
112
- return None, str(e)
 
5
  import uuid
6
 
7
  def to_bin(data):
8
+ """Convert data to binary format"""
9
  if isinstance(data, str):
10
+ return ''.join(format(ord(i), '08b') for i in data)
11
  elif isinstance(data, bytes):
12
+ return ''.join(format(i, '08b') for i in data)
13
  elif isinstance(data, np.ndarray):
14
+ return [format(i, '08b') for i in data]
15
  elif isinstance(data, int) or isinstance(data, np.uint8):
16
+ return format(data, '08b')
17
  else:
18
  raise TypeError("Type not supported.")
19
 
20
  def encode(image_path, secret_data):
21
+ """Encode watermark into image"""
22
  try:
23
  # Read the image
24
  image = cv2.imread(image_path)
25
  if image is None:
26
  return None, "Failed to read image"
27
+
28
  # Calculate maximum bytes for encoding
29
+ max_bytes = (image.shape[0] * image.shape[1] * 3) // 8
30
 
31
+ # Add delimiters to secret data
32
+ secret_data = f"START{secret_data}END"
33
+
34
+ # Check if the data can fit in the image
35
+ if len(secret_data) * 8 > max_bytes:
36
+ return None, "Watermark is too large for image size"
 
37
 
38
  # Convert data to binary
39
+ binary_secret_data = to_bin(secret_data)
40
  data_len = len(binary_secret_data)
41
+
42
+ # Create output image
43
+ watermarked_image = image.copy()
44
  data_index = 0
45
 
46
+ # Embed the data
47
+ for i in range(watermarked_image.shape[0]):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  if data_index >= data_len:
49
  break
50
+ for j in range(watermarked_image.shape[1]):
51
+ if data_index >= data_len:
52
+ break
53
+ for k in range(3):
54
+ if data_index >= data_len:
55
+ break
56
+ # Get binary pixel value
57
+ binary_pixel = to_bin(watermarked_image[i, j, k])
58
+ # Replace least significant bit
59
+ new_binary = binary_pixel[:-1] + binary_secret_data[data_index]
60
+ watermarked_image[i, j, k] = int(new_binary, 2)
61
+ data_index += 1
62
+
63
+ return watermarked_image, None
64
  except Exception as e:
65
  return None, f"Error during encoding: {str(e)}"
66
 
67
  def decode(image_path):
68
+ """Decode watermark from image"""
69
  try:
70
  # Read the image
71
+ if isinstance(image_path, str):
72
+ image = cv2.imread(image_path)
73
+ else:
74
+ # Handle PIL Image input
75
+ image = cv2.cvtColor(np.array(Image.open(image_path)), cv2.COLOR_RGB2BGR)
76
+
77
  if image is None:
78
  return "Failed to read image"
79
+
80
  binary_data = ""
81
+
82
+ # Extract LSB from each pixel
83
+ for i in range(image.shape[0]):
84
+ for j in range(image.shape[1]):
85
+ for k in range(3):
86
+ binary_pixel = to_bin(image[i, j, k])
87
+ binary_data += binary_pixel[-1]
88
 
89
  # Convert binary to text
90
+ text_data = ""
91
+ for i in range(0, len(binary_data), 8):
92
+ byte = binary_data[i:i+8]
93
+ if len(byte) == 8:
94
+ text_data += chr(int(byte, 2))
95
+ # Check for end marker
96
+ if "END" in text_data:
97
+ # Extract the actual message between START and END
98
+ start_idx = text_data.find("START")
99
+ end_idx = text_data.find("END")
100
+ if start_idx != -1 and end_idx != -1:
101
+ return text_data[start_idx+5:end_idx]
102
 
103
+ return "No watermark found"
 
104
  except Exception as e:
105
  return f"Error during decoding: {str(e)}"
106
 
107
  def png_encode(im_name, extra):
108
+ """Encode watermark into PNG metadata"""
109
  try:
110
  im = Image.open(im_name)
111
  info = PngImagePlugin.PngInfo()
 
113
 
114
  unique_id = str(uuid.uuid4())[:8]
115
  filename, ext = os.path.splitext(im_name)
116
+ new_filename = f"{filename}_{unique_id}.png"
117
  im.save(new_filename, "PNG", pnginfo=info)
118
 
119
  width, height = im.size
 
124
  png_encode_coords = (x, y, rect_width, rect_height)
125
 
126
  return new_filename, None
 
127
  except Exception as e:
128
+ return None, str(e)