summaryrefslogtreecommitdiff
path: root/jtanimator.py
diff options
context:
space:
mode:
authorstage7 <stage7@stg7.net>2024-09-28 23:45:49 +0200
committerstage7 <stage7@stg7.net>2024-09-28 23:45:49 +0200
commite88dcc3ceb38cb0d4494016df7556e968f97a678 (patch)
treea7b47817c9e63233b02fe9170b3278cee94331a5 /jtanimator.py
downloadjtanimator-1.0.tar.gz
jtanimator-1.0.tar.bz2
jtanimator-1.0.zip
First commitHEADv1.0master
Diffstat (limited to 'jtanimator.py')
-rw-r--r--jtanimator.py78
1 files changed, 78 insertions, 0 deletions
diff --git a/jtanimator.py b/jtanimator.py
new file mode 100644
index 0000000..0a863bb
--- /dev/null
+++ b/jtanimator.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+
+'''
+jtanimator v1.0, stage7
+
+A tool to convert PNG images into animations suitable for the JTPD-03-005 LED screen.
+
+The source image must be an RGB PNG (not indexed) using only the provided palette, stacking frames in vertical.
+The frames will be played in sequence, the first one being the topmost part. The image must be 32 pixels wide
+and 16 x n pixels high, n being the number of frames the final animation will have. The output should be exported
+to a file with .jt extension to be opened with the CoolLED1248 app.
+
+The palette is provided in GIMP format. Here it is for your reference in case you are unable to use this file:
+ 0 0 0 Black
+255 0 0 Red
+ 0 255 0 Green
+255 255 0 Yellow
+ 0 0 255 Blue
+255 0 255 Magenta
+ 0 255 255 Cyan
+255 255 255 White
+
+It has been tested with up to ~60 frames without issues. I have not done capacity tests so I do not know how many
+frames can the screen support. Bear in mind that 60 frames already take around 30 seconds to upload from the app.
+The speed of the animation can be edited in the app, but if you need something else by default you can change the
+"delays" attribute in the last line.
+
+I ignore if this script could work with models that have a different number of LEDs only changing a few numbers.
+Message me at @stage7@owo.cafe in the Fediverse if you try for yourself. I am also open to donations, just ask!
+
+This is free (libre) open-source software with no warranties. I will decide a license later, just please do not
+do anything nasty or take this script as your own. Thank you.
+'''
+
+import sys
+import PIL.Image as Image
+
+if len(sys.argv) < 2:
+ print("ERROR: The file name is missing.")
+ exit()
+
+filename = sys.argv[1]
+im = Image.open(filename)
+width, height = im.size
+
+if width != 32:
+ print("ERROR: The width of the image must be 32 pixels.")
+ exit()
+
+if height % 16 != 0:
+ print("ERROR: The height of the image must be divisible by 16.")
+ exit()
+
+bitsData = ["", "", ""]
+pixelNumber = 0
+
+for image in range(int(height / 16)):
+ for x in range(32):
+ for y in range(16):
+ col = im.getpixel((x, y + image * 16))
+ bitsData[0] += "1" if col[0] == 255 else "0"
+ bitsData[1] += "1" if col[1] == 255 else "0"
+ bitsData[2] += "1" if col[2] == 255 else "0"
+
+ if pixelNumber > 0 and pixelNumber % 8 == 7:
+ bitsData[0] += ","
+ bitsData[1] += ","
+ bitsData[2] += ","
+
+ pixelNumber += 1
+
+aniData = []
+for i in range(3):
+ tempData = bitsData[i].split(",")[:-1]
+ tempDataDec = [int(x, 2) for x in tempData]
+ aniData.extend(tempDataDec)
+
+print(f'[{{"data":{{"aniData":[{",".join(map(str, aniData))}],"aniType":1,"delays":300,"frameNum":{height // 16},"pixelHeight":16,"pixelWidth":32}},"dataType":0}}]')