from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * from PIL import Image, ExifTags class ImageTexture: def __init__(self, image_source, exif=None): self.id = None img = Image.open(image_source) self.exif = exif or ImageTexture.get_exif(img) img = ImageTexture.handle_orientation(img, exif) img = img.convert("RGBA") # Ensure the image is in RGBA mode self.width = img.width self.height = img.height self._img_data = img.tobytes("raw", "RGBA", 0, -1) # Convert image data to bytes def gl_init(self): if self.id: return #glPixelStorei(GL_UNPACK_ALIGNMENT, 1) self.id = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, self.id) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.width, self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self._img_data) #glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.width, img.height, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) del self._img_data # No longer needed, clear mem print(f"Loaded texture {self.id}") @staticmethod def get_exif(img): return { ExifTags.TAGS[k]: v for k, v in img.getexif().items() if k in ExifTags } @staticmethod def handle_orientation(img, exif): orientation = exif.get("Orientation", 1) if orientation == 3: return img.rotate(180, expand=True) if orientation == 6: return img.rotate(270, expand=True) if orientation == 8: return img.rotate( 90, expand=True) return img