Last modified on 16 August 2011, at 12:04

Creating images for the Amstrad

This article originally came from Kevin Thackers' archive at http://www.cpctech.org.uk.

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

  1. Choose 'New' from the 'File' menu. The 'New Image' dialog box will appear.
  2. 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.
  3. 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.
  4. 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.
  5. Choose RGB as the image type.
  6. Click on the 'OK' button to create the image. The image window will then be displayed.
  7. 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)