RenAzum's picture
Add application
f6cb6df
raw
history blame
4.16 kB
import cv2
import numpy as np
from PIL import Image, PngImagePlugin
import os
import uuid
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 encode(image_path, secret_data):
try:
# Read the image
image = cv2.imread(image_path)
if image is None:
return None, "Failed to read image"
# Calculate maximum bytes for encoding
n_bytes = (image.shape[0] * image.shape[1] * 3) // 8
# Prepare secret data
secret_data_with_delimiter = f'{secret_data}#####'
if len(secret_data_with_delimiter) + 5 >= n_bytes:
return None, "Watermark is too large for Image Size"
secret_data_with_delimiter += "====="
binary_secret_data = to_bin(secret_data_with_delimiter)
data_len = len(binary_secret_data)
# Create a copy of the image
watermarked_image = image.copy()
data_index = 0
# Encode the data
for i in range(watermarked_image.shape[0]):
for j in range(watermarked_image.shape[1]):
for k in range(3): # RGB channels
if data_index < data_len:
# Get the current pixel value
pixel = watermarked_image[i, j, k]
# Convert to binary and modify the least significant bit
binary_pixel = format(pixel, '08b')
new_pixel = binary_pixel[:-1] + binary_secret_data[data_index]
# Update the pixel value
watermarked_image[i, j, k] = int(new_pixel, 2)
data_index += 1
else:
break
if data_index >= data_len:
break
if data_index >= data_len:
break
return watermarked_image, None
except Exception as e:
return None, f"Error during encoding: {str(e)}"
def decode(image_path):
try:
# Read the image
image = cv2.imread(image_path)
if image is None:
return "Failed to read image"
binary_data = ""
# Extract the least significant bits
for i in range(image.shape[0]):
for j in range(image.shape[1]):
for k in range(3):
pixel = format(image[i, j, k], '08b')
binary_data += pixel[-1]
# Convert binary to text
decoded_data = ""
for i in range(0, len(binary_data), 8):
byte = binary_data[i:i+8]
if len(byte) == 8:
decoded_data += chr(int(byte, 2))
# Check for ending delimiter
if decoded_data[-5:] == "=====":
break
# Remove delimiters and return the message
if "#####" in decoded_data:
return decoded_data.split("#####")[0]
return "No watermark found"
except Exception as e:
return f"Error during decoding: {str(e)}"
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, "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)