Instructions for The GIMP v1.2
Introduction
The GIMP is a free image editing package available on Linux and Windows.
Creating new images
Images in CPC's mode 0
- Choose 'New' from the 'File' menu. The 'New Image' dialog box will appear.
- Break the link between the X resolution and the Y resolution by clicking on the chain next to these items.
NOTE: Now you can change the X and Y resolutions independently. This is needed because the pixels in CPC's mode 0 are not square. - Set the X resolution to be half that of the Y resolution. e.g. set the X resolution to 36 pixels/inch and Y resolution to 72 pixels/inch.
NOTE: The pixels in CPC's mode 0 are rectangular and they are twice as wide as they are tall. By setting the X and Y resolution to these values (so that the ratio of width/height is 2:1), this will simulate the resolution. - Now set the Width and Height of the image to the desired width and height in pixels. e.g. 160x200 for the default screen, 192x280 for overscan.
NOTE: This defines the dimensions of the image in pixels. - Choose RGB as the image type.
- Click on the 'OK' button to create the image. The image window will then be displayed.
- Right click with the mouse within the image window and select 'Dot for Dot' from the 'View' menu. Ensure this is turned off.
NOTE: The 'Dot for Dot' option displays each pixel as a square. In CPC's mode 0 the pixels are not square.
When turned off, the pixels will be displayed according to the X and Y resolution defined above. So now each pixel should be a rectangle as we require. This option allows you to simulate the rectangular pixels of CPC's mode 0.
Sprite/Tile images
Often your sprites, background tiles or characters in a font are all made from one or more images of the same size.
To make creating these easier use the grid feature in the GIMP.
While the image is displayed perform the following steps to turn on the grid:
- Choose 'Configure Grid' from the 'Image' menu.
- If your sprites are not square, then in the Spacing section break the link below the Width and Height boxes. This will now allow you to enter different values for width and height.
- In the 'Spacing' section enter the width and height of the tile (in pixels) in the appropiate boxes.
- Click on the 'OK' button once you are done.
- Now Choose 'Show Grid' from the 'View' menu.
- You may find that you can't see the Grid. If that is the case then go back to 'Configure Grid' and choose a foregound colour with which the grid will be drawn. Click on the 'OK' button to confirm the colour.
Converting existing RGB images to the CPC 3-level color palette
This converts an image to CPC MODE 0:
- Maximize saturation (Colors > Hue-Saturation; the CPC palette is very saturated, so this will give a better result)
- Image > Scale Image to 320xXX (proportional scaling)
- Then scale to 160xXX (non-proportional scaling)
- Colors > Posterize with a setting of 3 levels
- Convert to CPC palette (Image > Mode > Indexed, select Use custom palette and point to the CPC color palette file[1]. Also select Remove unused colors)
- Check Image > Image Properties for the number of colors used
- If they are more than 16 (or whatever maximum you want):
- Use Tools > Selection Tools > By Color Select and Tools > Color Picker to replace the necessary number of colors with others
- Image > Mode > RGB, then convert to the CPC palette again and check in the info window for the number of colors used
- Crop to 160x200 if necessary
- Save in a format your converter to SCR understands
Sample Python programs for conversion to SCR
You need to save your image in PPM ASCII format in Gimp for this. Also, Python needs to have NumPy installed. The program will also print the necessary INK statements for BASIC.
The first variant is for MODE 0 images:
#!/usr/bin/env python # Transform ASCII PPM image to Amstrad SCR file (MODE 0) # 2011-08-09 from numpy import * import struct f = file("input.ppm", "r") # input file binfile = open('ouput.scr', 'wb') # output file pal = [[0,0,0],[255,255,255]] # initial palette def byte_bin(x): r="" for n in range(7,-1,-1): v=2**n if x>=v: x-=v r+="1" else: r+="0" return r v = [0,0,0] count = zeros((256)) f.readline() f.readline() g = f.readline() f.readline() xdim, ydim = [int(q) for q in g.split()] for y in range(ydim): for x in range(xdim): for c in range(3): g = f.readline() v[c] = int(g) app = 1 for n,p in enumerate(pal): if p[0]==v[0] and p[1]==v[1] and p[2]==v[2]: app = 0 count[n]+=1 if app: pal.append([v[0],v[1],v[2]]) for pn,pp in enumerate(pal): print pn,pp,int(count[pn]) f.seek(0) f.readline() f.readline() g = f.readline() f.readline() b=zeros((xdim,ydim)) c=zeros((2**14)) for y in range(ydim): for x in range(xdim): for c in range(3): g = f.readline() v[c] = int(g) n = -1 for m,p in enumerate(pal): if p[0]==v[0] and p[1]==v[1] and p[2]==v[2]: n = m b[x,y]=n for cl in range(8): # line in character for y in range(ydim/8): for x in range(0,xdim,2): aa=byte_bin(b[x,y*8+cl])[4:] bb=byte_bin(b[x+1,y*8+cl])[4:] oo=(aa[3]+bb[3]+aa[1]+bb[1] + aa[2]+bb[2]+aa[0]+bb[0]) oo=int(oo,2) data = struct.pack("B", oo) binfile.write(data) data = struct.pack("B", 0) for t in range(48): binfile.write(data) binfile.close() ik="" for n,p in enumerate(pal): v=p[1]//127*9 + p[0]//127*3 + p[2]//127 lst= [":ink ", str(n), ",", str(v)] ik+= "".join(lst) print ik
For MODE 1 images, replace the second-to-last loop with:
for cl in range(8): # line in character for y in range(ydim/8): for x in range(0,xdim,4): aa=byte_bin(b[x,y*8+cl])[6:] bb=byte_bin(b[x+1,y*8+cl])[6:] cc=byte_bin(b[x+2,y*8+cl])[6:] dd=byte_bin(b[x+3,y*8+cl])[6:] oo=(aa[1]+bb[1]+cc[1]+dd[1] + aa[0]+bb[0]+cc[0]+dd[0]) oo=int(oo,2) data = struct.pack("B", oo) binfile.write(data) data = struct.pack("B", 0) for t in range(48): binfile.write(data)
Finally, here is a program for MODE 2. Input file must an ASCII PBM this time.
# Transform PBM image to Amstrad SCR file (MODE 2) # 2011-08-09 from numpy import * import struct f = file("input.pbm", "r") binfile = open('output.scr', 'wb') def byte_bin(x): r="" for n in range(7,-1,-1): v=2**n if x>=v: x-=v r+="1" else: r+="0" return r f.readline() f.readline() g = f.readline() xdim, ydim = [int(q) for q in g.split()] b=zeros((xdim,ydim)) x, y = 0, 0 while True: g = f.readline() if g=="": break for q in g: if q in ("0", "1"): b[x,y] = int(q) x+=1 if x==xdim: x=0 y+=1 for cl in range(8): # line in character for y in range(ydim/8): for x in range(0,xdim,8): oo = 0 for q in range(8): if b[x+7-q,y*8+cl]==1: oo += 2**q data = struct.pack("B", oo) binfile.write(data) data = struct.pack("B", 0) for t in range(48): binfile.write(data) binfile.close()
Links
- Retro Computing GIMP filters (Python filters for GIMP to create optionally dithered images for the CPC, Spectrum, BBC Micro, C64, and Apple II)