-
Notifications
You must be signed in to change notification settings - Fork 0
/
Image2D.py
102 lines (83 loc) · 3.94 KB
/
Image2D.py
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
from PIL import Image
import numpy as np
class Image2D:
ALPHA = 96
LUMINANCE = 97
LUMINANCE_ALPHA = 98
RGB = 99
RGBA = 100
def __init__(self, format=None, width=None, height=None, image=None, palette=None):
if format and width and height and image is not None:
if palette:
self.handle = self.create_palettized(format, width, height, image, palette)
else:
self.handle = self.create(format, width, height, image)
elif format and width and height:
self.handle = self.create_mutable(format, width, height)
elif isinstance(image, Image.Image):
self.handle = self.create_image(format, image)
elif isinstance(image, bytearray):
self.handle = self.create_image_impl(image)
@staticmethod
def create(format, width, height, image):
if image is None:
raise ValueError("Image cannot be None")
if not isinstance(image, Image.Image):
raise TypeError("Image must be an instance of PIL.Image")
img_width = image.width
img_height = image.height
# Create and return some form of handle (in this case, we'll simulate with a tuple)
return (format, img_width, img_height, np.array(image))
@staticmethod
def create_palettized(format, width, height, image, palette):
if image is None or palette is None:
raise ValueError("Image and palette cannot be None")
# For simplicity, assume the creation returns a tuple with the image and palette information
return (format, width, height, np.array(image), np.array(palette))
@staticmethod
def create_mutable(format, width, height):
# Assuming this creates a mutable empty image (simulated with numpy array)
return (format, width, height, np.zeros((height, width, 3), dtype=np.uint8))
@staticmethod
def create_image(format, image):
if not isinstance(image, Image.Image):
raise TypeError("Image must be an instance of PIL.Image")
width, height = image.size
# Return a simulated handle
return (format, width, height, np.array(image))
@staticmethod
def create_image_impl(data, offset, length):
# Simulate creating image from byte array (just returns a tuple for simplicity)
return (None, len(data), 1, data)
@staticmethod
def get_image_rgb(img, offset, scanlength, x, y, width, height):
# Convert region of image to RGB array (using numpy for simplicity)
rgb = np.array(img.crop((x, y, x+width, y+height)))
return rgb
@staticmethod
def is_opaque(img):
return img.mode == "RGBA" # Check if image has alpha channel
def get_format(self):
return self.handle[0]
def get_width(self):
return self.handle[1]
def get_height(self):
return self.handle[2]
def is_mutable(self):
return isinstance(self.handle, np.ndarray)
def set(self, x, y, width, height, data):
# Simulate setting a portion of an image with new data
self.handle[y:y+height, x:x+width] = np.array(data).reshape(height, width, -1)
def set_rgb(self, rgb, x, y, width, height, is_opaque):
# Simulate setting RGB values (assuming is_opaque determines if alpha channel is added)
rgb_array = np.array(rgb).reshape((height, width, 3))
if is_opaque:
rgb_array = np.dstack((rgb_array, np.ones((height, width, 1), dtype=np.uint8)*255)) # Add alpha channel
self.set(x, y, width, height, rgb_array)
# Example usage
if __name__ == "__main__":
img = Image.open('example.png')
image_2d = Image2D(Image2D.RGBA, img.width, img.height, img)
print("Image format:", image_2d.get_format())
print("Image width:", image_2d.get_width())
print("Image height:", image_2d.get_height())