# modified from ado1928/pix2msch try: import struct, zlib, os, base64 from PIL import Image except Exception as e: print("You're missing a package!") print() print(e) input() colorarray = [ 217, 157, 115, 140, 127, 169, 235, 238, 245, 178, 198, 210, 247, 203, 164, 39, 39, 39, 141, 161, 227, 249, 163, 199, 119, 119, 119, 83, 86, 92, 203,217, 127, 244,186, 110, 243, 233, 121, 116, 87, 206, 255, 121, 94, 255, 170, 95 ] #convert array of ints into a list of tuples, then into a palette tuple_array = [tuple(colorarray[t*3:t*3+3]) for t in range(len(colorarray)//3)] palette = Image.new("P", (16, 16)) palette.putpalette(colorarray*16) palette.load() def quantize(img, dither, transparency_treshold): #invalid input checking img = Image.open(img) transparency_treshold = int(transparency_treshold) #sphagetti img = img.convert("RGBA") # image imgq = img.convert("RGB") # fully opaque image imgq = imgq._new(imgq.im.convert("P", 1 if dither else 0, palette.im)) #where the actual quantization happens imgA = Image.new("RGBA", img.size) pixels = imgA.load() imgq = imgq.convert("RGB") for y in range(img.size[1]): for x in range(img.size[0]): if img.getpixel((x, y))[3] >= transparency_treshold: #transparency treshold pixels[x, y] = imgq.getpixel((x, y)) else: pixels[x, y] = (0, 0, 0, 0) # print("Quantization complete") return imgA # imgfile - Path to the image # name - Name of the schematic # save_location - Save location, i guess # dither - Whether to use dithering (True or False, 1 or 0) # transparency_treshold - Below which alpha level to stop displaying (0-255), where 0 is show everything and 255 is show only fully opaque # mode - Either "path" or "clipboard". Whether to save the schematic as .msch or to copy it into clipboard def pix2msch(imgfile = None, name = "schematic", save_location = None, dither = True, transparency_treshold = 127, mode = "path" ): #sad face tiles = [] #input checking if mode == "path" and not(os.path.isdir(os.path.expandvars(save_location))): print("not a path") exit() img = quantize(imgfile, dither, transparency_treshold) img = img.rotate(-90, expand=True) width, height = img.size for y in range(height): for x in range(width): if img.getpixel((x, y))[3] > 1: tiles.append((x, y, tuple_array.index(img.getpixel((x, y))[0:3]))) # print("Converted pixels into an array of tiles") class ByteBuffer(): #so desparate i had to write my own byte buffer def __init__(self, data=bytearray()): self.data = data def writeShort(self, int): self.data += struct.pack(">H", int) def writeUTF(self, str): self.writeShort(len(str)) self.data += bytes(str.encode("UTF")) def writeByte(self, int): self.data += struct.pack("b", int) def writeInt(self, int): self.data += struct.pack(">i", int) #write header and all of that stuff data = ByteBuffer() data.writeShort(height) data.writeShort(width) data.writeByte(1) data.writeUTF("name") data.writeUTF(name) data.writeByte(1) data.writeUTF("sorter") data.writeInt(len(tiles)) # print("Header written") for tile in tiles: #write tiles data.writeByte(0) data.writeShort(tile[1]) data.writeShort(tile[0]) data.writeInt(tile[2]) data.writeByte(0) # print("Tile data written") if mode == "path": os.chdir(os.path.expandvars(save_location)) file = open(name + ".msch", "wb") file.write(b"msch\x00"+zlib.compress(data.data)) file.close() # print("Successfully saved {0} ".format(name + ".msch")) else: try: import pyperclip except ImportError: print("To use this feature, you need to have the pyperclip module") exit() else: pyperclip.copy(base64.standard_b64encode(b"msch\x00"+zlib.compress(data.data)).decode()) print("Schematic converted to base64, and put into clipboard")