fantos commited on
Commit
1c8c36e
·
verified ·
1 Parent(s): 4263379

Update utils.py

Browse files
Files changed (1) hide show
  1. utils.py +35 -33
utils.py CHANGED
@@ -63,7 +63,10 @@ class WatermarkProcessor:
63
  return im_name, f"Error adding watermark: {str(e)}"
64
 
65
  def encode(self, image_path, watermark_text, metadata=None):
66
- """Encode watermark using simple LSB steganography"""
 
 
 
67
  try:
68
  image = cv2.imread(image_path)
69
  if image is None:
@@ -76,18 +79,20 @@ class WatermarkProcessor:
76
  'metadata': metadata or {}
77
  }
78
 
79
- # Convert data to string with end marker
80
  json_str = json.dumps(data, ensure_ascii=False)
81
- secret_data = json_str + "#####"
82
-
83
- # Convert string to binary (using utf-8 encoding)
84
- binary_data = ''.join(format(ord(char), '08b') for char in secret_data)
 
 
85
 
86
  # Check capacity
87
  if len(binary_data) > image.shape[0] * image.shape[1] * 3:
88
  return image_path, "Error: Image too small for watermark data"
89
 
90
- # Embed data
91
  data_index = 0
92
  for i in range(image.shape[0]):
93
  for j in range(image.shape[1]):
@@ -95,8 +100,8 @@ class WatermarkProcessor:
95
  if data_index < len(binary_data):
96
  pixel = int(image[i, j, k])
97
  # Clear the LSB
98
- pixel = pixel & 0xFE # Clear last bit
99
- # Set the LSB according to our data
100
  pixel = pixel | (int(binary_data[data_index]) & 1)
101
  image[i, j, k] = np.uint8(pixel)
102
  data_index += 1
@@ -107,7 +112,7 @@ class WatermarkProcessor:
107
  if data_index >= len(binary_data):
108
  break
109
 
110
- # Save result
111
  output_path = f"watermarked_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
112
  cv2.imwrite(output_path, image)
113
  return output_path, "Watermark added successfully"
@@ -116,9 +121,12 @@ class WatermarkProcessor:
116
  return image_path, f"Error in encoding: {str(e)}"
117
 
118
  def decode(self, image_path):
119
- """Decode watermark using simple LSB steganography"""
 
 
 
120
  try:
121
- # Try PNG metadata first
122
  try:
123
  im = Image.open(image_path)
124
  if "TXT" in im.info:
@@ -130,34 +138,28 @@ class WatermarkProcessor:
130
  if image is None:
131
  raise ValueError("Could not read image file")
132
 
133
- # Extract binary data
134
  binary_data = ''
135
  for i in range(image.shape[0]):
136
  for j in range(image.shape[1]):
137
  for k in range(3):
138
  binary_data += str(image[i, j, k] & 1)
139
 
140
- # Convert binary to text
 
 
 
 
 
141
  text = ''
142
- for i in range(0, len(binary_data), 8):
143
- if i + 8 <= len(binary_data):
144
- byte = binary_data[i:i+8]
145
- text += chr(int(byte, 2))
146
-
147
- # Check for end marker
148
- if "#####" in text:
149
- # Extract content before marker
150
- text = text.split("#####")[0]
151
- try:
152
- # Parse JSON
153
- data = json.loads(text)
154
- return json.dumps(data, ensure_ascii=False, indent=2)
155
- except json.JSONDecodeError:
156
- return text
157
- break
158
-
159
- return "Error: No valid watermark found"
160
-
161
  except Exception as e:
162
  return f"Error in decoding: {str(e)}"
163
 
 
63
  return im_name, f"Error adding watermark: {str(e)}"
64
 
65
  def encode(self, image_path, watermark_text, metadata=None):
66
+ """Encode watermark using simple LSB steganography with header
67
+
68
+ 헤더(32비트)는 watermark 데이터(UTF-8 문자열)의 길이(문자수)를 이진 문자열로 저장합니다.
69
+ """
70
  try:
71
  image = cv2.imread(image_path)
72
  if image is None:
 
79
  'metadata': metadata or {}
80
  }
81
 
82
+ # Convert data to string (UTF-8)
83
  json_str = json.dumps(data, ensure_ascii=False)
84
+ # 헤더: 32비트에 데이터 길이(문자수)를 저장
85
+ data_length = len(json_str)
86
+ header = format(data_length, '032b')
87
+ # 본문: 문자를 8비트 이진수로 변환
88
+ body = ''.join(format(ord(char), '08b') for char in json_str)
89
+ binary_data = header + body
90
 
91
  # Check capacity
92
  if len(binary_data) > image.shape[0] * image.shape[1] * 3:
93
  return image_path, "Error: Image too small for watermark data"
94
 
95
+ # Embed data into LSB of each pixel
96
  data_index = 0
97
  for i in range(image.shape[0]):
98
  for j in range(image.shape[1]):
 
100
  if data_index < len(binary_data):
101
  pixel = int(image[i, j, k])
102
  # Clear the LSB
103
+ pixel = pixel & 0xFE
104
+ # Set the LSB according to our data bit
105
  pixel = pixel | (int(binary_data[data_index]) & 1)
106
  image[i, j, k] = np.uint8(pixel)
107
  data_index += 1
 
112
  if data_index >= len(binary_data):
113
  break
114
 
115
+ # Save result image (PNG: lossless)
116
  output_path = f"watermarked_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
117
  cv2.imwrite(output_path, image)
118
  return output_path, "Watermark added successfully"
 
121
  return image_path, f"Error in encoding: {str(e)}"
122
 
123
  def decode(self, image_path):
124
+ """Decode watermark using simple LSB steganography with header
125
+
126
+ 먼저 32비트를 읽어 watermark 데이터의 길이(문자수)를 구한 후, 해당 길이만큼의 데이터를 추출합니다.
127
+ """
128
  try:
129
+ # PNG 메타데이터 먼저 확인
130
  try:
131
  im = Image.open(image_path)
132
  if "TXT" in im.info:
 
138
  if image is None:
139
  raise ValueError("Could not read image file")
140
 
141
+ # 모든 픽셀의 LSB를 읽어 이진 문자열 생성
142
  binary_data = ''
143
  for i in range(image.shape[0]):
144
  for j in range(image.shape[1]):
145
  for k in range(3):
146
  binary_data += str(image[i, j, k] & 1)
147
 
148
+ # 먼저 헤더(32비트)를 읽어 데이터 길이(문자수)를 결정
149
+ header = binary_data[:32]
150
+ data_length = int(header, 2)
151
+ total_bits = data_length * 8
152
+ # 본문 데이터 읽기
153
+ message_bits = binary_data[32:32 + total_bits]
154
  text = ''
155
+ for i in range(0, len(message_bits), 8):
156
+ byte = message_bits[i:i+8]
157
+ text += chr(int(byte, 2))
158
+ try:
159
+ data = json.loads(text)
160
+ return json.dumps(data, ensure_ascii=False, indent=2)
161
+ except json.JSONDecodeError:
162
+ return text
 
 
 
 
 
 
 
 
 
 
 
163
  except Exception as e:
164
  return f"Error in decoding: {str(e)}"
165