Spaces:
Sleeping
Sleeping
File size: 4,443 Bytes
1618e9b b2358ad aa56dd1 1618e9b aa56dd1 059deb6 66655a5 059deb6 66655a5 059deb6 66655a5 059deb6 66655a5 059deb6 66655a5 059deb6 1618e9b dbea623 66655a5 dbea623 66655a5 dbea623 66655a5 dbea623 66655a5 db1515c 66655a5 dbea623 66655a5 dbea623 66655a5 dbea623 66655a5 dbea623 1618e9b dbea623 66655a5 f00a6e1 dbea623 66655a5 dbea623 66655a5 f00a6e1 66655a5 dbea623 66655a5 dbea623 66655a5 f00a6e1 dbea623 1618e9b dbea623 66655a5 dbea623 059deb6 dbea623 66655a5 dbea623 66655a5 |
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 |
import cv2
import numpy as np
from PIL import Image, PngImagePlugin
import os
import uuid
def to_bin(data):
"""Convert data to binary format"""
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 encode(image_path, secret_data):
"""Encode watermark into image"""
try:
# Read the image
image = cv2.imread(image_path)
if image is None:
return None, "Failed to read image"
# Calculate maximum bytes for encoding
max_bytes = (image.shape[0] * image.shape[1] * 3) // 8
# Add delimiters to secret data
secret_data = f"START{secret_data}END"
# Check if the data can fit in the image
if len(secret_data) * 8 > max_bytes:
return None, "Watermark is too large for image size"
# Convert data to binary
binary_secret_data = to_bin(secret_data)
data_len = len(binary_secret_data)
# Create output image
watermarked_image = image.copy()
data_index = 0
# Embed the data
for i in range(watermarked_image.shape[0]):
if data_index >= data_len:
break
for j in range(watermarked_image.shape[1]):
if data_index >= data_len:
break
for k in range(3):
if data_index >= data_len:
break
# Get binary pixel value
binary_pixel = to_bin(watermarked_image[i, j, k])
# Replace least significant bit
new_binary = binary_pixel[:-1] + binary_secret_data[data_index]
watermarked_image[i, j, k] = int(new_binary, 2)
data_index += 1
return watermarked_image, None
except Exception as e:
return None, f"Error during encoding: {str(e)}"
def decode(image_path):
"""Decode watermark from image"""
try:
# Read the image
if isinstance(image_path, str):
image = cv2.imread(image_path)
else:
# Handle PIL Image input
image = cv2.cvtColor(np.array(Image.open(image_path)), cv2.COLOR_RGB2BGR)
if image is None:
return "Failed to read image"
binary_data = ""
# Extract LSB from each pixel
for i in range(image.shape[0]):
for j in range(image.shape[1]):
for k in range(3):
binary_pixel = to_bin(image[i, j, k])
binary_data += binary_pixel[-1]
# Convert binary to text
text_data = ""
for i in range(0, len(binary_data), 8):
byte = binary_data[i:i+8]
if len(byte) == 8:
text_data += chr(int(byte, 2))
# Check for end marker
if "END" in text_data:
# Extract the actual message between START and END
start_idx = text_data.find("START")
end_idx = text_data.find("END")
if start_idx != -1 and end_idx != -1:
return text_data[start_idx+5:end_idx]
return "No watermark found"
except Exception as e:
return f"Error during decoding: {str(e)}"
def png_encode(im_name, extra):
"""Encode watermark into PNG metadata"""
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}.png"
im.save(new_filename, "PNG", pnginfo=info)
width, height = im.size
rect_width, rect_height = 200, 50
x = width - rect_width - 10
y = height - rect_height - 10
global png_encode_coords
png_encode_coords = (x, y, rect_width, rect_height)
return new_filename, None
except Exception as e:
return None, str(e)
|