Difference between revisions of "Creating images for the Amstrad"
(added credits to Kevin Thacker) |
(→Sample Python programs for conversion to SCR) |
||
(7 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | [[Category:Graphic]] | ||
<div style="border: 1px solid rgb(228, 222, 222); margin: 0px 0px 5px; padding: 0.5em 1em; background-color: rgb(249, 249, 249);"><center>'''''This article originally came from Kevin Thackers' archive at [http://www.cpctech.org.uk http://www.cpctech.org.uk].'''''</center></div> | <div style="border: 1px solid rgb(228, 222, 222); margin: 0px 0px 5px; padding: 0.5em 1em; background-color: rgb(249, 249, 249);"><center>'''''This article originally came from Kevin Thackers' archive at [http://www.cpctech.org.uk http://www.cpctech.org.uk].'''''</center></div> | ||
Line 29: | Line 30: | ||
* Now Choose 'Show Grid' from the 'View' menu. | * 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. | * 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[http://www.cpctech.org.uk/download/gimp.zip]. 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: | ||
+ | |||
+ | <pre> | ||
+ | #!/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 | ||
+ | </pre> | ||
+ | |||
+ | For MODE 1 images, replace the second-to-last loop with: | ||
+ | |||
+ | <pre> | ||
+ | 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) | ||
+ | </pre> | ||
+ | |||
+ | Finally, here is a program for MODE 2. Input file must an ASCII P'''B'''M this time. | ||
+ | |||
+ | <pre> | ||
+ | # 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() | ||
+ | </pre> | ||
+ | |||
+ | ==Links== | ||
+ | |||
+ | *[http://code.google.com/p/newoldtv/downloads/detail?name=retro_computing_gimp_0.0.5.tar.gz ''Retro Computing GIMP filters''] (Python filters for GIMP to create optionally dithered images for the CPC, Spectrum, BBC Micro, C64, and Apple II) |
Latest revision as of 12:04, 16 August 2011
Instructions for The GIMP v1.2
Contents
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)