Skip to content

Commit 88cfc3a

Browse files
committed
png to rle conversion in pynthon + Test touch screen
1 parent f278434 commit 88cfc3a

File tree

5 files changed

+317
-0
lines changed

5 files changed

+317
-0
lines changed

python-png_to_rle/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# python-rle
2+
Convert a PNG file into a human-readable RLE format by using Python 3 and Pillow.
3+
4+
<h3>If you don't have Pillow installed</h3>
5+
Run the following command from the command prompt:
6+
<pre>pip install pillow</pre>
7+
8+
<h3>What is RLE</h3>
9+
According to Wikipedia, RLE stands for "Run-length encoding (RLE)". <br/><br/>
10+
Run-length encoding is a very simple form of lossless data compression in which runs of data (that is, sequences in which the same data value occurs in many consecutive data elements) are stored as a single data value and count, rather than as the original run.
11+
<br/><br/>
12+
<i>For example, this string:</i><br/>
13+
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW<br/><br/>
14+
<i>...becomes this after using RLE:</i><br/>
15+
12W1B12W3B24W1B14W<br/><br/>
16+
This script simply converts a binary PNG image into an RLE-type file format.
17+
<h3>Example</h3>
18+
<i>Original image</i><br/>
19+
<img src="https://github.com/anwserman/python-rle/blob/master/input/golfcourse.png">
20+
<i>Sample output</i><br/>
21+
<pre>
22+
#Image Dimensions
23+
Width: 683
24+
Height: 384
25+
26+
27+
#Image Palette
28+
255, 0, 128
29+
0, 102, 0
30+
0, 255, 0
31+
66, 255, 66
32+
0, 0, 255
33+
255, 255, 0
34+
128, 128, 128
35+
0, 0, 0
36+
37+
#Pixel Count
38+
0: 42670
39+
1: 48
40+
0: 631
41+
1: 53
42+
0: 627
43+
1: 61
44+
0: 55
45+
2: 55
46+
0: 509
47+
1: 67
48+
0: 48
49+
2: 63
50+
51+
... truncated for brevity
52+
</pre>
53+
<h3>Included commands</h3>
54+
<b>open_png(filename):</b> Open up a PNG file by file path, and read it into memory<br/>
55+
<b>get_color_atpoint(point):</b> Get a tuple with RGB values at a given point in an image, by passing in a tuple with X,Y coordinates<br/>
56+
<b>read_rle_fromstream(stream):</b> Read in RLE information from a file, by passing in a file stream <br/>
57+
<b>write_memory_tofile(filename):</b> Write out the image in memory as a binary file <br/>
58+
<b>write_rle_tostream(filename):</b> Write out RLE information to a file, by passing in a file stream<br/>
462 Bytes
Loading
1.34 KB
Loading

python-png_to_rle/png_to_rle.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import os, sys
2+
from PIL import Image
3+
4+
class RLEBitmap:
5+
width = 0
6+
height = 0
7+
pixels = None
8+
image = None
9+
10+
#basic constructor
11+
def __init__(self):
12+
self.image = None
13+
self.pixels = None
14+
self.height = 0
15+
self.width = 0
16+
17+
def open_png(self, filename):
18+
#open up the image
19+
self.image = Image.open(filename)
20+
#get the pixel data
21+
self.pixels = self.image.load()
22+
#get the width and height
23+
self.width, self.height = self.image.size
24+
print ("width=",self.width)
25+
print ("height=",self.height)
26+
27+
def get_color_atpoint(self, point):
28+
#return the pixel color as a tuple, at the given point
29+
return (self.pixels[point[0], point[1]])
30+
31+
#read an image from a file stream
32+
def read_rle_fromstream(self, stream):
33+
#colors used within the image, this can be a list and not a dictionary
34+
colors = []
35+
colorCount = 0
36+
colorIndex = 0
37+
38+
#iterator data
39+
i = 0
40+
x = 0
41+
y = 0
42+
43+
#reset bitmap data
44+
self.image = None
45+
self.pixels = None
46+
47+
#read in and skip the first line, it's the header description
48+
49+
self.line1 = stream.readline()
50+
print("line1=", self.line1)
51+
#get the image width and height
52+
self.line2 = stream.readline()
53+
print("line2=", self.line2)
54+
self.width = int(self.line2.split(':')[1])
55+
self.height = int(stream.readline().split(':')[1])
56+
#skip the new line
57+
stream.readline()
58+
59+
#set up our bitmap in memory
60+
self.image = Image.new("RGB", (self.width, self.height))
61+
62+
#read in the image palette, and skip the first line as it's the palette description
63+
stream.readline()
64+
65+
#interate through until we hit whitespace
66+
sI = stream.readline()
67+
while not sI.isspace():
68+
#split the line into rgb components
69+
sISplit = sI.split(',')
70+
#read in the values as an RGB tuple
71+
colors.append((int(sISplit[0]), int(sISplit[1]), int(sISplit[2])))
72+
#read in the next new line
73+
sI = stream.readline()
74+
75+
#now we read in the pixel count, and skip the first line as it's the header description
76+
stream.readline()
77+
78+
#iterate through until we hit whitespae
79+
#first line
80+
sI = stream.readline()
81+
while not sI.isspace():
82+
#split the line into index/count components
83+
sISplit = sI.split(':')
84+
#get the RGB index value that we need based on index
85+
colorIndex = int(sISplit[0])
86+
#get the count of how many times we need to loop through this color
87+
colorCount = int(sISplit[1])
88+
89+
i = 0
90+
for i in range(0, colorCount):
91+
self.image.putpixel((x, y), colors[colorIndex])
92+
x += 1
93+
94+
if (x == (self.width)):
95+
x = 0
96+
y += 1
97+
98+
#read in the next new line
99+
sI = stream.readline()
100+
101+
#once the image has been constructed in memory, dump the pixel data into a table
102+
self.pixels = self.image.load()
103+
104+
#print rle conversion
105+
def write_rle_tostream(self):
106+
#colors used within the image
107+
colors = {}
108+
#store the RLE data
109+
pixels = []
110+
pixelsTFE = [] # this is the format required by TFTe_SPI
111+
#store the color in use
112+
currentColor = None
113+
currentColorCount = 0
114+
115+
#iterator data
116+
x = 0
117+
y = 0
118+
119+
#iterate through image
120+
#row by row
121+
for y in range(0, self.height):
122+
#column by column
123+
for x in range(0, self.width):
124+
#get the current pixel
125+
newColor = self.pixels[x, y]
126+
127+
#compare new color versus existing color
128+
if newColor != currentColor:
129+
#we don't want to do this if currentColor is nothing
130+
if currentColor != None:
131+
#add current (existing) color to our dictionary
132+
#and give it an index value (lookup value)
133+
#this is rudimentary lookup table for both saving the color data below and for saving/reading the file later
134+
colors.setdefault(currentColor, len(colors.keys()))
135+
#return the index value
136+
colorIndex = colors[currentColor]
137+
#add the color and pixel count to our list
138+
pixels.append((colorIndex, currentColorCount))
139+
while currentColorCount > 128:
140+
if currentColor == 0:
141+
pixelsTFE.append(127)
142+
else :
143+
pixelsTFE.append(255)
144+
currentColorCount = currentColorCount - 128
145+
if currentColor != 0:
146+
currentColorCount = currentColorCount+128
147+
pixelsTFE.append(currentColorCount-1)
148+
#set the new color to our currentcolor
149+
currentColor = newColor
150+
#set the count equal to 1, as we need to count it as part of the new run
151+
currentColorCount = 1
152+
else:
153+
currentColor = newColor
154+
currentColorCount = 1
155+
else:
156+
currentColorCount += 1
157+
158+
#flush out the last of the colors we were working on, into the array
159+
colors.setdefault(currentColor, len(colors.keys()))
160+
colorIndex = colors[currentColor]
161+
pixels.append((colorIndex, currentColorCount))
162+
while currentColorCount > 128:
163+
if currentColor == 0:
164+
pixelsTFE.append(127)
165+
else :
166+
pixelsTFE.append(255)
167+
currentColorCount = currentColorCount - 128
168+
if currentColor != 0:
169+
currentColorCount = currentColorCount+128
170+
pixelsTFE.append(currentColorCount-1)
171+
172+
print("colors =", colors)
173+
print("pixels (on/off , amount) =" , pixels)
174+
print("rle = " ,pixelsTFE)
175+
176+
#some tests
177+
#open up a PNG and write it to a RLE document
178+
rb = RLEBitmap()
179+
#rb.open_png('input\golfcourse.png')
180+
rb.open_png('more1_button.png')
181+
#fs = open('output\more1_button.rle','w')
182+
#fs = open('output\golfcourse.rle','w')
183+
rb.write_rle_tostream()
184+
#fs.close()
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
2+
#include "SPI.h"
3+
4+
#define TFT_MISO 19
5+
#define TFT_MOSI 23
6+
#define TFT_SCLK 18
7+
#define TFT_CS 13 //15 // Chip select control pin
8+
#define TFT_DC 14// 2 // Data Command control pin
9+
10+
#define TFT_RST 12// 4 // Reset pin (could connect to RST pin)
11+
12+
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST
13+
#define TOUCH_CS 27 //21 // Chip select pin (T_CS) of touch screen
14+
15+
#define TFT_LED_PIN 25
16+
17+
18+
19+
void setup() {
20+
Serial.begin(115200);
21+
Serial.println("\n\nStarting...");
22+
23+
24+
pinMode(TFT_DC, OUTPUT);
25+
digitalWrite(TFT_DC, HIGH); // Data/Command high = data mode
26+
27+
pinMode(TFT_RST, OUTPUT);
28+
digitalWrite(TFT_RST, HIGH); // Set high, do not share pin with another SPI device
29+
30+
pinMode(TFT_LED_PIN , OUTPUT) ;
31+
digitalWrite(TFT_LED_PIN , HIGH) ;
32+
33+
34+
SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI, -1);
35+
Serial.println("\n\nEnd of setup...");
36+
//SPI.endTransaction();
37+
38+
tft.begin();
39+
40+
tft.setRotation(1);
41+
tft.fillScreen(TFT_NAVY); // Clear screen to navy background
42+
43+
}
44+
45+
void readOneAxis(uint8_t axis){
46+
uint16_t data ;
47+
//Serial.print("1");
48+
SPI.endTransaction();
49+
SPI.beginTransaction(SPISettings(2500000, MSBFIRST, SPI_MODE0));
50+
//Serial.print("2");
51+
digitalWrite( TOUCH_CS, LOW) ; // select the device
52+
//pinMode(TFT_RST, INPUT );
53+
SPI.transfer(axis);
54+
//Serial.print("3");
55+
data = SPI.transfer16(axis) ;
56+
//Serial.print("4");
57+
Serial.print(" "); Serial.print(data);
58+
digitalWrite( TOUCH_CS, HIGH) ; // select the device
59+
SPI.endTransaction();
60+
//Serial.print("5");
61+
62+
}
63+
#define X_AXIS 0xD3
64+
#define Y_AXIS 0x93
65+
#define Z_AXIS 0xB1
66+
67+
68+
void loop() {
69+
// put your main code here, to run repeatedly:
70+
readOneAxis(X_AXIS);
71+
readOneAxis(Y_AXIS);
72+
readOneAxis(Z_AXIS);
73+
Serial.println("");
74+
//delay(500);
75+
}

0 commit comments

Comments
 (0)