Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ##CC0 Kaelygon 2025
- import math
- import numpy as np
- from PIL import Image
- from dataclasses import dataclass, field
- class ImgConverter:
- #amogus matrix
- amogus = np.array([
- [0,1,1,1,0],
- [1,1,0,0,0],
- [1,1,1,1,0],
- [0,1,0,1,0],
- [0,0,0,0,0],
- ])
- amogus = (amogus/(np.max(amogus)+1))**2.0 #gamma correct
- dither_width = 1.0
- amogus*=dither_width
- pixels = None #Don't mutate this after init
- pixels_output = None #copy of pixels that can be modified
- size = None
- def __init__(self, input_path):
- self.imgToOkPixels(input_path)
- #private
- def _limitDepth(self, colors: np.ndarray, color_depth: np.array):
- return np.round(colors*color_depth)/color_depth
- #public
- def imgToOkPixels(self, img_path: str):
- in_img = Image.open(img_path).convert("RGBA")
- rgba = np.array(in_img, dtype=np.float64) / 255.0
- self.pixels = rgba.reshape(-1, 4)
- self.pixels_output = self.pixels
- self.size = in_img.size
- def saveImage(self, output_path: str, color_depth: np.array):
- rgba = self.pixels_output
- rgba = self._limitDepth(rgba, color_depth)
- rgba = np.clip(np.round(rgba * 255), 0, 255).astype(np.uint8)
- rgba = rgba.reshape((self.size[1], self.size[0], 4))
- img = Image.fromarray(rgba, "RGBA")
- img.save(output_path)
- def ditherAmogus(self, color_depth: [float]*3):
- #palettize
- color_depth_rgb = color_depth[:3]
- pixels = self.pixels_output[...,:3].copy()
- y_idxs, x_idxs = np.divmod(np.arange(len(pixels)), self.size[0])
- m_h, m_w = self.amogus.shape
- thresholds = self.amogus[y_idxs % m_h, x_idxs % m_w]
- pixel_gaps=1.0/np.array(color_depth_rgb)
- #apply mask
- new_cols = pixels + thresholds[:,None] * pixel_gaps
- new_cols = self._limitDepth(new_cols, color_depth_rgb)
- alpha = self.pixels_output[..., 3].copy()
- self.pixels_output = np.concatenate([new_cols, alpha[:, None]], axis=1)
- @dataclass
- class ConvertPreset:
- image: str #file names
- output: str
- color_depth: np.array #number of axis steps [R,G,B,A]
- def palettizeImage(preset: ConvertPreset):
- image_ok = ImgConverter(preset.image)
- image_ok.ditherAmogus(preset.color_depth)
- image_ok.saveImage(preset.output, preset.color_depth)
- if __name__ == '__main__':
- preset_list = [
- ConvertPreset(
- image = "./testImg/KaelygonSeawing.png",
- output = "./output/palettizedImg.png",
- color_depth = [6,6,7,8] #r,g,b,a
- )
- ]
- palettizeImage( preset_list[0] )
Advertisement
Add Comment
Please, Sign In to add comment