-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
png to rle conversion in pynthon + Test touch screen
- Loading branch information
Showing
5 changed files
with
317 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# python-rle | ||
Convert a PNG file into a human-readable RLE format by using Python 3 and Pillow. | ||
|
||
<h3>If you don't have Pillow installed</h3> | ||
Run the following command from the command prompt: | ||
<pre>pip install pillow</pre> | ||
|
||
<h3>What is RLE</h3> | ||
According to Wikipedia, RLE stands for "Run-length encoding (RLE)". <br/><br/> | ||
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. | ||
<br/><br/> | ||
<i>For example, this string:</i><br/> | ||
WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW<br/><br/> | ||
<i>...becomes this after using RLE:</i><br/> | ||
12W1B12W3B24W1B14W<br/><br/> | ||
This script simply converts a binary PNG image into an RLE-type file format. | ||
<h3>Example</h3> | ||
<i>Original image</i><br/> | ||
<img src="https://github.com/anwserman/python-rle/blob/master/input/golfcourse.png"> | ||
<i>Sample output</i><br/> | ||
<pre> | ||
#Image Dimensions | ||
Width: 683 | ||
Height: 384 | ||
|
||
|
||
#Image Palette | ||
255, 0, 128 | ||
0, 102, 0 | ||
0, 255, 0 | ||
66, 255, 66 | ||
0, 0, 255 | ||
255, 255, 0 | ||
128, 128, 128 | ||
0, 0, 0 | ||
|
||
#Pixel Count | ||
0: 42670 | ||
1: 48 | ||
0: 631 | ||
1: 53 | ||
0: 627 | ||
1: 61 | ||
0: 55 | ||
2: 55 | ||
0: 509 | ||
1: 67 | ||
0: 48 | ||
2: 63 | ||
|
||
... truncated for brevity | ||
</pre> | ||
<h3>Included commands</h3> | ||
<b>open_png(filename):</b> Open up a PNG file by file path, and read it into memory<br/> | ||
<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/> | ||
<b>read_rle_fromstream(stream):</b> Read in RLE information from a file, by passing in a file stream <br/> | ||
<b>write_memory_tofile(filename):</b> Write out the image in memory as a binary file <br/> | ||
<b>write_rle_tostream(filename):</b> Write out RLE information to a file, by passing in a file stream<br/> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
import os, sys | ||
from PIL import Image | ||
|
||
class RLEBitmap: | ||
width = 0 | ||
height = 0 | ||
pixels = None | ||
image = None | ||
|
||
#basic constructor | ||
def __init__(self): | ||
self.image = None | ||
self.pixels = None | ||
self.height = 0 | ||
self.width = 0 | ||
|
||
def open_png(self, filename): | ||
#open up the image | ||
self.image = Image.open(filename) | ||
#get the pixel data | ||
self.pixels = self.image.load() | ||
#get the width and height | ||
self.width, self.height = self.image.size | ||
print ("width=",self.width) | ||
print ("height=",self.height) | ||
|
||
def get_color_atpoint(self, point): | ||
#return the pixel color as a tuple, at the given point | ||
return (self.pixels[point[0], point[1]]) | ||
|
||
#read an image from a file stream | ||
def read_rle_fromstream(self, stream): | ||
#colors used within the image, this can be a list and not a dictionary | ||
colors = [] | ||
colorCount = 0 | ||
colorIndex = 0 | ||
|
||
#iterator data | ||
i = 0 | ||
x = 0 | ||
y = 0 | ||
|
||
#reset bitmap data | ||
self.image = None | ||
self.pixels = None | ||
|
||
#read in and skip the first line, it's the header description | ||
|
||
self.line1 = stream.readline() | ||
print("line1=", self.line1) | ||
#get the image width and height | ||
self.line2 = stream.readline() | ||
print("line2=", self.line2) | ||
self.width = int(self.line2.split(':')[1]) | ||
self.height = int(stream.readline().split(':')[1]) | ||
#skip the new line | ||
stream.readline() | ||
|
||
#set up our bitmap in memory | ||
self.image = Image.new("RGB", (self.width, self.height)) | ||
|
||
#read in the image palette, and skip the first line as it's the palette description | ||
stream.readline() | ||
|
||
#interate through until we hit whitespace | ||
sI = stream.readline() | ||
while not sI.isspace(): | ||
#split the line into rgb components | ||
sISplit = sI.split(',') | ||
#read in the values as an RGB tuple | ||
colors.append((int(sISplit[0]), int(sISplit[1]), int(sISplit[2]))) | ||
#read in the next new line | ||
sI = stream.readline() | ||
|
||
#now we read in the pixel count, and skip the first line as it's the header description | ||
stream.readline() | ||
|
||
#iterate through until we hit whitespae | ||
#first line | ||
sI = stream.readline() | ||
while not sI.isspace(): | ||
#split the line into index/count components | ||
sISplit = sI.split(':') | ||
#get the RGB index value that we need based on index | ||
colorIndex = int(sISplit[0]) | ||
#get the count of how many times we need to loop through this color | ||
colorCount = int(sISplit[1]) | ||
|
||
i = 0 | ||
for i in range(0, colorCount): | ||
self.image.putpixel((x, y), colors[colorIndex]) | ||
x += 1 | ||
|
||
if (x == (self.width)): | ||
x = 0 | ||
y += 1 | ||
|
||
#read in the next new line | ||
sI = stream.readline() | ||
|
||
#once the image has been constructed in memory, dump the pixel data into a table | ||
self.pixels = self.image.load() | ||
|
||
#print rle conversion | ||
def write_rle_tostream(self): | ||
#colors used within the image | ||
colors = {} | ||
#store the RLE data | ||
pixels = [] | ||
pixelsTFE = [] # this is the format required by TFTe_SPI | ||
#store the color in use | ||
currentColor = None | ||
currentColorCount = 0 | ||
|
||
#iterator data | ||
x = 0 | ||
y = 0 | ||
|
||
#iterate through image | ||
#row by row | ||
for y in range(0, self.height): | ||
#column by column | ||
for x in range(0, self.width): | ||
#get the current pixel | ||
newColor = self.pixels[x, y] | ||
|
||
#compare new color versus existing color | ||
if newColor != currentColor: | ||
#we don't want to do this if currentColor is nothing | ||
if currentColor != None: | ||
#add current (existing) color to our dictionary | ||
#and give it an index value (lookup value) | ||
#this is rudimentary lookup table for both saving the color data below and for saving/reading the file later | ||
colors.setdefault(currentColor, len(colors.keys())) | ||
#return the index value | ||
colorIndex = colors[currentColor] | ||
#add the color and pixel count to our list | ||
pixels.append((colorIndex, currentColorCount)) | ||
while currentColorCount > 128: | ||
if currentColor == 0: | ||
pixelsTFE.append(127) | ||
else : | ||
pixelsTFE.append(255) | ||
currentColorCount = currentColorCount - 128 | ||
if currentColor != 0: | ||
currentColorCount = currentColorCount+128 | ||
pixelsTFE.append(currentColorCount-1) | ||
#set the new color to our currentcolor | ||
currentColor = newColor | ||
#set the count equal to 1, as we need to count it as part of the new run | ||
currentColorCount = 1 | ||
else: | ||
currentColor = newColor | ||
currentColorCount = 1 | ||
else: | ||
currentColorCount += 1 | ||
|
||
#flush out the last of the colors we were working on, into the array | ||
colors.setdefault(currentColor, len(colors.keys())) | ||
colorIndex = colors[currentColor] | ||
pixels.append((colorIndex, currentColorCount)) | ||
while currentColorCount > 128: | ||
if currentColor == 0: | ||
pixelsTFE.append(127) | ||
else : | ||
pixelsTFE.append(255) | ||
currentColorCount = currentColorCount - 128 | ||
if currentColor != 0: | ||
currentColorCount = currentColorCount+128 | ||
pixelsTFE.append(currentColorCount-1) | ||
|
||
print("colors =", colors) | ||
print("pixels (on/off , amount) =" , pixels) | ||
print("rle = " ,pixelsTFE) | ||
|
||
#some tests | ||
#open up a PNG and write it to a RLE document | ||
rb = RLEBitmap() | ||
#rb.open_png('input\golfcourse.png') | ||
rb.open_png('more1_button.png') | ||
#fs = open('output\more1_button.rle','w') | ||
#fs = open('output\golfcourse.rle','w') | ||
rb.write_rle_tostream() | ||
#fs.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
|
||
#include "SPI.h" | ||
|
||
#define TFT_MISO 19 | ||
#define TFT_MOSI 23 | ||
#define TFT_SCLK 18 | ||
#define TFT_CS 13 //15 // Chip select control pin | ||
#define TFT_DC 14// 2 // Data Command control pin | ||
|
||
#define TFT_RST 12// 4 // Reset pin (could connect to RST pin) | ||
|
||
//#define TFT_RST -1 // Set TFT_RST to -1 if display RESET is connected to ESP32 board RST | ||
#define TOUCH_CS 27 //21 // Chip select pin (T_CS) of touch screen | ||
|
||
#define TFT_LED_PIN 25 | ||
|
||
|
||
|
||
void setup() { | ||
Serial.begin(115200); | ||
Serial.println("\n\nStarting..."); | ||
|
||
|
||
pinMode(TFT_DC, OUTPUT); | ||
digitalWrite(TFT_DC, HIGH); // Data/Command high = data mode | ||
|
||
pinMode(TFT_RST, OUTPUT); | ||
digitalWrite(TFT_RST, HIGH); // Set high, do not share pin with another SPI device | ||
|
||
pinMode(TFT_LED_PIN , OUTPUT) ; | ||
digitalWrite(TFT_LED_PIN , HIGH) ; | ||
|
||
|
||
SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI, -1); | ||
Serial.println("\n\nEnd of setup..."); | ||
//SPI.endTransaction(); | ||
|
||
tft.begin(); | ||
|
||
tft.setRotation(1); | ||
tft.fillScreen(TFT_NAVY); // Clear screen to navy background | ||
|
||
} | ||
|
||
void readOneAxis(uint8_t axis){ | ||
uint16_t data ; | ||
//Serial.print("1"); | ||
SPI.endTransaction(); | ||
SPI.beginTransaction(SPISettings(2500000, MSBFIRST, SPI_MODE0)); | ||
//Serial.print("2"); | ||
digitalWrite( TOUCH_CS, LOW) ; // select the device | ||
//pinMode(TFT_RST, INPUT ); | ||
SPI.transfer(axis); | ||
//Serial.print("3"); | ||
data = SPI.transfer16(axis) ; | ||
//Serial.print("4"); | ||
Serial.print(" "); Serial.print(data); | ||
digitalWrite( TOUCH_CS, HIGH) ; // select the device | ||
SPI.endTransaction(); | ||
//Serial.print("5"); | ||
|
||
} | ||
#define X_AXIS 0xD3 | ||
#define Y_AXIS 0x93 | ||
#define Z_AXIS 0xB1 | ||
|
||
|
||
void loop() { | ||
// put your main code here, to run repeatedly: | ||
readOneAxis(X_AXIS); | ||
readOneAxis(Y_AXIS); | ||
readOneAxis(Z_AXIS); | ||
Serial.println(""); | ||
//delay(500); | ||
} |