Skip to content

Instantly share code, notes, and snippets.

@digarok
Created October 31, 2018 02:27
Show Gist options
  • Save digarok/e71000ef686f02d0848a1f418312b61e to your computer and use it in GitHub Desktop.
Save digarok/e71000ef686f02d0848a1f418312b61e to your computer and use it in GitHub Desktop.
Convert (320x200) RGB image to an Apple IIgs $C1 (Uncompressed SHR) file
# Invoke like:
# $ python genc1.py mypic.png output.shr
from PIL import Image
from math import sqrt
from sys import argv
img = Image.open(argv[1])
rgb_img = img.convert("RGB") # create the pixel map
iigs_colors = set()
cvals = [0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]
for r in cvals:
for g in cvals:
for b in cvals:
iigs_colors.add((r,g,b))
def distance3d((x1, y1, z1), (x2, y2, z2)):
return sqrt((x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2)
def uniquepalette(image):
hist = set()
for j in range(image.size[1]):
for i in range(image.size[0]):
hist.add(image.getpixel((i,j)))
return hist
def iigspalette(pal_set):
new = set()
for rgb in pal_set:
new.add(min(iigs_colors, key=lambda x: distance3d(x, rgb)))
return new
### MAIN
orig_pal = sorted(uniquepalette(rgb_img)) # source palette from gif/png
iigs_pal = iigspalette(orig_pal) # our 4-bit colorspace versions
image_pal = list(iigs_pal) # as a list to index palette colors
bytes = []
for j in range(rgb_img.size[1]):
for i in range(rgb_img.size[0]/2): # 2 horizontal pixels at a time to make a byte
p1 = rgb_img.getpixel((i*2,j))
p2 = rgb_img.getpixel(((i*2)+1,j))
nearest_idx1 = image_pal.index(min(image_pal, key=lambda x: distance3d(x, p1)))
nearest_idx2 = image_pal.index(min(image_pal, key=lambda x: distance3d(x, p2)))
byte = (nearest_idx1*16) + (nearest_idx2)
bytes.append(byte)
for _ in xrange(0,0x100): # SCBs, all zero
bytes.append(0)
# GB0R
for color in image_pal: # write palette colors
r,g,b = color
gb = ((g/16)*16)+(b/16) #actually need to step down these 8 bit values to 4 bits per color so /16
r = r/16
bytes.append(gb)
bytes.append(r)
# now pad
print(0x200 - (len(image_pal)*2))
for _ in range(0x200 - (len(image_pal)*2)):
bytes.append(0)
newFile = open(argv[2], "wb")
newFileByteArray = bytearray(bytes)
newFile.write(newFileByteArray)
print("Wrote {} bytes to {}.".format(len(bytes),argv[2]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment