Spaces:
Sleeping
Sleeping
File size: 3,846 Bytes
1618e9b b2358ad aa56dd1 1618e9b aa56dd1 059deb6 1618e9b 059deb6 1618e9b 059deb6 1618e9b 059deb6 1618e9b dbea623 1618e9b dbea623 f00a6e1 dbea623 f00a6e1 dbea623 1618e9b f00a6e1 dbea623 f00a6e1 dbea623 1618e9b dbea623 059deb6 dbea623 |
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 |
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
# Check if the secret data is too large
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"
# Add ending delimiter
secret_data_with_delimiter += "====="
# Convert data to binary
binary_secret_data = to_bin(secret_data_with_delimiter)
data_len = len(binary_secret_data)
data_index = 0
# Encode the data into the image
for i in range(image.shape[0]):
for j in range(image.shape[1]):
pixel = image[i, j]
for color_channel in range(3):
if data_index < data_len:
# Get the binary value of the pixel
binary_value = to_bin(pixel[color_channel])
# Replace the least significant bit
new_binary = binary_value[:-1] + binary_secret_data[data_index]
# Update the pixel with the new value
pixel[color_channel] = int(new_binary, 2)
data_index += 1
image[i, j] = pixel
if data_index >= data_len:
break
if data_index >= data_len:
break
return 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 = ""
for row in image:
for pixel in row:
for color_channel in pixel:
binary_data += to_bin(color_channel)[-1]
# Convert binary to text
all_bytes = [binary_data[i: i + 8] for i in range(0, len(binary_data), 8)]
decoded_data = ""
for byte in all_bytes:
decoded_data += chr(int(byte, 2))
if decoded_data[-5:] == "=====":
break
# Remove delimiters
return decoded_data[:-5].split("#####")[0]
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)
|