Root/
Source at commit 267d16656c561d62e859b225576d251eb25dbb7c created 13 years 1 month ago. By Neil Stockbridge, There are now two example Pre fonts | |
---|---|
1 | #!/usr/bin/env python |
2 | # |
3 | # This tool depends on the "pygame" package. |
4 | # |
5 | # The Ben NanoNote has a "delta" arrangement of the pixels on its LCD: |
6 | # |
7 | # even rows: R G B|R G B|.. |
8 | # odd rows: G B R|G B R|.. |
9 | # |
10 | # Note that the odd-numbered rows are shifted 1/6th of pixel width left. |
11 | # |
12 | # A white pixel at (0,1) will appear shifted 1/6th of a pixel left relative to |
13 | # a white pixel at (0,0) resulting in jaggies on vertical lines. |
14 | # |
15 | # This tool processes a sheet of 8x8 font glyphs into a sheet of 4x8 font |
16 | # glyphs using individual green and magenta "pixels" to achieve twice the |
17 | # horizontal resolution. It also compensates for the unusual screen on the |
18 | # NanoNote. |
19 | # |
20 | # NOTE: On the even rows, a single pixel is discarded that would have been made |
21 | # up of the red component of the first column along with the blue component of |
22 | # the last column. On odds rows, the green component of the first column is |
23 | # discarded. This means that last column of the source image is ignored. |
24 | # |
25 | # Example usage: |
26 | # |
27 | # tools/un-fuzzy.py fonts/pre-4x8-font.png /tmp/un-fuzzy-4x8-font.tga |
28 | # |
29 | # Then use GIMP to convert the .tga file to a .pnm file. Imagemagick seems to |
30 | # create P3 .pnm files yet setfont2 can only load P6 .pnm files presently. |
31 | # |
32 | |
33 | import sys |
34 | import pygame |
35 | |
36 | |
37 | # Check and grab the command line arguments |
38 | if len( sys.argv) < 3: |
39 | print "Use: %s source-image-file target-image-file(BMP|TGA) [grid]" % sys.argv[0] |
40 | sys.exit( 1) |
41 | |
42 | path_to_source_file = sys.argv[ 1] |
43 | path_to_target_file = sys.argv[ 2] |
44 | grid = ( 4 == len( sys.argv)) |
45 | |
46 | # Load the source image and create the target image with the same number of |
47 | # rows but half the number of columns |
48 | source_image = pygame.image.load( path_to_source_file) |
49 | target_image = pygame.Surface( (source_image.get_width()/2, source_image.get_height())) |
50 | |
51 | |
52 | class Colour: |
53 | def __init__( self): |
54 | self.red = 0 |
55 | self.green = 0 |
56 | self.blue = 0 |
57 | |
58 | def isnt_black( self): |
59 | return self.red != 0 or self.green != 0 or self.blue != 0 |
60 | |
61 | def __repr__( self): |
62 | return "(%i,%i,%i)" % ( self.red, self.green, self.blue) |
63 | |
64 | |
65 | def update_pixel( self, location, colour): |
66 | current_state = list( self.get_at( location)) |
67 | # NOTE that the new luminances are logical-ORed with the current state of |
68 | # the pixels since no component should be added to twice, which means that |
69 | # no overflow of component values should be possible |
70 | current_state[ 0] |= colour.red |
71 | current_state[ 1] |= colour.green |
72 | current_state[ 2] |= colour.blue |
73 | self.set_at( location, current_state) |
74 | |
75 | |
76 | for row in range( source_image.get_height()): |
77 | for column in range( source_image.get_width() - 1): |
78 | pixel = source_image.get_at( (column, row)) |
79 | # "pixel" should be monochrome |
80 | red = pixel[ 0] |
81 | green = pixel[ 1] |
82 | blue = pixel[ 2] |
83 | if red != green or green != blue: |
84 | raise Exception("not monochrome at (%i,%i)"%( column, row)) |
85 | |
86 | luminance = red |
87 | |
88 | # The pixel at ( x, y) in the target image encodes two virtual pixels: one |
89 | # from the green component and one from the magenta component made by |
90 | # combining the blue component and the red component of the pixel |
91 | # immediately to the right of this pixel |
92 | # For odd-numbered rows the virtual pixels are: |
93 | # 1) magenta made from blue and red |
94 | # 2) the green component of the pixel to the right |
95 | |
96 | # The luminance of the pixel at ( x, y) in the source image is encoded in |
97 | # different ways depending whether the row is odd or even-numbered and |
98 | # whether the column is odd or even-numbered |
99 | |
100 | left = Colour() |
101 | right = Colour() |
102 | |
103 | # If preparing SubLCD for a grid-based LCD rather than a Delta LCD.. |
104 | if grid: |
105 | if 0 == column & 1: |
106 | # The luminance of this pixel is provided by the green component of the |
107 | # pixel at ( x, y) |
108 | left.green = luminance |
109 | else: |
110 | # The luminance of this pixel is provided by the magenta component that |
111 | # is distributed across two pixels ( the blue component of the pixel at |
112 | # ( x, y) and the red component of the pixel at ( x+1, y)) |
113 | left.blue = luminance |
114 | right.red = luminance |
115 | else: |
116 | # If this row is even-numbered.. |
117 | if 0 == row & 1: |
118 | # If this column is even-numbered.. |
119 | if 0 == column & 1: |
120 | # The luminance of this pixel is provided by the green component of the |
121 | # pixel at ( x, y) |
122 | left.green = luminance |
123 | else: |
124 | # The luminance of this pixel is provided by the magenta component that |
125 | # is distributed across two pixels ( the blue component of the pixel at |
126 | # ( x, y) and the red component of the pixel at ( x+1, y)) |
127 | left.blue = luminance |
128 | right.red = luminance |
129 | else: |
130 | if 0 == column & 1: |
131 | # The luminance of this pixel is provided by the magenta component ( |
132 | # the sum of the red and blue components) of the pixel at ( x, y) |
133 | left.red = luminance |
134 | left.blue = luminance |
135 | else: |
136 | # The luminance of this pixel is provided by the green component of the |
137 | # pixel at ( x+1, y) |
138 | right.green = luminance |
139 | update_pixel( target_image, (column/2,row), left) |
140 | #print repr((column,row)) |
141 | #print "L"+repr(left) |
142 | #print "R"+repr(right) |
143 | if right.isnt_black(): |
144 | update_pixel( target_image, (column/2+1,row), right) |
145 | |
146 | pygame.image.save( target_image, path_to_target_file) |
147 | |
148 |
Branches:
master